Skip to content

Commit

Permalink
Store the unwrapped types with a TypeModifierStack
Browse files Browse the repository at this point in the history
  • Loading branch information
wravery committed May 23, 2021
1 parent e3033c4 commit 21ec432
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 22 deletions.
18 changes: 15 additions & 3 deletions include/RequestLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,26 @@ using ResponseFieldChildren = std::variant<ResponseFieldList, ResponseUnionOptio
struct ResponseField
{
std::shared_ptr<const schema::BaseType> type;
TypeModifierStack modifiers;
std::string_view name;
std::string_view cppName;
std::optional<tao::graphqlpeg::position> position;
std::optional<ResponseFieldChildren> children;
};

struct RequestVariable
{
std::shared_ptr<const schema::BaseType> type;
TypeModifierStack modifiers;
std::string_view name;
std::string_view cppName;
std::string_view defaultValueString;
response::Value defaultValue;
std::optional<tao::graphqlpeg::position> position;
std::optional<ResponseFieldChildren> children;
};

using RequestVariableList = std::vector<RequestVariable>;

struct RequestOptions
{
const std::string requestFilename;
Expand All @@ -60,7 +72,7 @@ class RequestLoader
std::string_view getOperationType() const noexcept;
std::string_view getRequestText() const noexcept;

const ResponseFieldList& getVariables() const noexcept;
const RequestVariableList& getVariables() const noexcept;
const ResponseType& getResponseType() const noexcept;

private:
Expand Down Expand Up @@ -113,7 +125,7 @@ class RequestLoader
const peg::ast_node* _operation = nullptr;
std::string_view _operationName;
std::string_view _operationType;
ResponseFieldList _variables;
RequestVariableList _variables;
ResponseType _responseType;

FragmentDefinitionMap _fragments;
Expand Down
67 changes: 48 additions & 19 deletions src/RequestLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ std::string_view RequestLoader::getRequestText() const noexcept
return trimWhitespace(_requestText);
}

const ResponseFieldList& RequestLoader::getVariables() const noexcept
const RequestVariableList& RequestLoader::getVariables() const noexcept
{
return _variables;
}
Expand Down Expand Up @@ -581,7 +581,7 @@ void RequestLoader::collectVariables() noexcept
{
peg::for_each_child<peg::variable>(*_operation,
[this](const peg::ast_node& variableDefinition) {
ResponseField variable;
RequestVariable variable;
TypeVisitor variableType;
service::schema_location defaultValueLocation;

Expand Down Expand Up @@ -613,22 +613,24 @@ void RequestLoader::collectVariables() noexcept

const auto [type, modifiers] = variableType.getType();

variable.type = getSchemaType(type, modifiers);
variable.position = variableDefinition.begin();
variable.type = _schema->LookupType(type);
variable.modifiers = modifiers;

if (!variable.defaultValueString.empty()
&& variable.defaultValue.type() == response::Type::Null
&& (modifiers.empty() || modifiers.front() != service::TypeModifier::Nullable))
{
std::ostringstream error;

error << "Expected Non-Null default value for variable name: " << variable.name
<< " line: " << defaultValueLocation.line
<< " column: " << defaultValueLocation.column;
error << "Expected Non-Null default value for variable name: " << variable.name;

throw std::runtime_error(error.str());
throw service::schema_exception {
{ service::schema_error { error.str(), std::move(defaultValueLocation) } }
};
}

variable.position = variableDefinition.begin();

_variables.push_back(std::move(variable));
});
}
Expand Down Expand Up @@ -742,6 +744,41 @@ void RequestLoader::SelectionVisitor::visitField(const peg::ast_node& field)
responseField.type = (*itr)->type().lock();
}

bool wrapped = true;
bool nonNull = false;

while (wrapped)
{
switch (responseField.type->kind())
{
case introspection::TypeKind::NON_NULL:
nonNull = true;
responseField.type = responseField.type->ofType().lock();
break;

case introspection::TypeKind::LIST:
if (!nonNull)
{
responseField.modifiers.push_back(service::TypeModifier::Nullable);
}

nonNull = false;
responseField.modifiers.push_back(service::TypeModifier::List);
responseField.type = responseField.type->ofType().lock();
break;

default:
if (!nonNull)
{
responseField.modifiers.push_back(service::TypeModifier::Nullable);
}

nonNull = false;
wrapped = false;
break;
}
}

const peg::ast_node* selection = nullptr;

peg::on_first_child<peg::selection_set>(field, [&selection](const peg::ast_node& child) {
Expand All @@ -750,20 +787,12 @@ void RequestLoader::SelectionVisitor::visitField(const peg::ast_node& field)

if (selection)
{
auto ofType = responseField.type;

while (ofType->kind() == introspection::TypeKind::NON_NULL
|| ofType->kind() == introspection::TypeKind::LIST)
{
ofType = ofType->ofType().lock();
}

switch (ofType->kind())
switch (responseField.type->kind())
{
case introspection::TypeKind::OBJECT:
case introspection::TypeKind::INTERFACE:
{
SelectionVisitor selectionVisitor { _fragments, _schema, ofType };
SelectionVisitor selectionVisitor { _fragments, _schema, responseField.type };

selectionVisitor.visit(*selection);

Expand All @@ -780,7 +809,7 @@ void RequestLoader::SelectionVisitor::visitField(const peg::ast_node& field)
case introspection::TypeKind::UNION:
{
ResponseUnionOptions options;
const auto& possibleTypes = ofType->possibleTypes();
const auto& possibleTypes = responseField.type->possibleTypes();

for (const auto& weakType : possibleTypes)
{
Expand Down

0 comments on commit 21ec432

Please sign in to comment.