Skip to content

Commit 970375f

Browse files
committed
Parse interfaces implementing interfaces
1 parent 69abcf9 commit 970375f

File tree

7 files changed

+99
-17
lines changed

7 files changed

+99
-17
lines changed

include/SchemaGenerator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class Generator
5757
void outputObjectImplementation(
5858
std::ostream& sourceFile, const ObjectType& objectType, bool isQueryType) const;
5959
void outputObjectIntrospection(std::ostream& sourceFile, const ObjectType& objectType) const;
60+
void outputIntrospectionInterfaces(std::ostream& sourceFile, std::string_view cppType,
61+
const std::vector<std::string_view>& interfaces) const;
6062
void outputIntrospectionFields(
6163
std::ostream& sourceFile, std::string_view cppType, const OutputFieldList& fields) const;
6264
std::string getArgumentDefaultValue(

include/SchemaLoader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ struct InterfaceType
176176
{
177177
std::string_view type;
178178
std::string_view cppType;
179+
std::vector<std::string_view> interfaces;
179180
OutputFieldList fields;
180181
std::string_view description;
181182
};

include/graphqlservice/internal/Grammar.h

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,29 +151,28 @@ struct block_escape_sequence : seq<backslash_token, block_quote_token>
151151
};
152152

153153
struct block_quote_character
154-
: plus<not_at<ascii::eol>, not_at<block_quote_token>, not_at<block_escape_sequence>, source_character>
154+
: plus<not_at<ascii::eol>, not_at<block_quote_token>, not_at<block_escape_sequence>,
155+
source_character>
155156
{
156157
};
157158

158159
struct block_quote_empty_line : star<not_at<eol>, space>
159160
{
160161
};
161162

162-
struct block_quote_line_content
163-
: plus<sor<block_escape_sequence, block_quote_character>>
163+
struct block_quote_line_content : plus<sor<block_escape_sequence, block_quote_character>>
164164
{
165165
};
166166

167167
struct block_quote_line : seq<block_quote_empty_line, block_quote_line_content>
168168
{
169169
};
170170

171-
struct block_quote_content_lines: opt<list<sor<block_quote_line, block_quote_empty_line>, eol>>
171+
struct block_quote_content_lines : opt<list<sor<block_quote_line, block_quote_empty_line>, eol>>
172172
{
173173
};
174174

175-
struct block_quote_content
176-
: seq<block_quote_content_lines, must<block_quote_token>>
175+
struct block_quote_content : seq<block_quote_content_lines, must<block_quote_token>>
177176
{
178177
};
179178

@@ -732,7 +731,11 @@ struct interface_type_definition_interface_name : seq<plus<ignored>, interface_n
732731
{
733732
};
734733

735-
struct interface_type_definition_directives : opt<star<ignored>, directives>
734+
struct interface_type_definition_implements_interfaces : opt<plus<ignored>, implements_interfaces>
735+
{
736+
};
737+
738+
struct interface_type_definition_directives : seq<star<ignored>, directives>
736739
{
737740
};
738741

@@ -742,9 +745,13 @@ struct interface_type_definition_fields_definition : seq<star<ignored>, fields_d
742745

743746
struct interface_type_definition_content
744747
: seq<interface_type_definition_interface_name,
745-
sor<seq<interface_type_definition_directives,
748+
sor<seq<interface_type_definition_implements_interfaces,
749+
opt<interface_type_definition_directives>,
750+
interface_type_definition_fields_definition>,
751+
seq<interface_type_definition_implements_interfaces,
752+
interface_type_definition_directives,
746753
interface_type_definition_fields_definition>,
747-
interface_type_definition_directives>>
754+
interface_type_definition_implements_interfaces>>
748755
{
749756
};
750757

@@ -1085,9 +1092,26 @@ struct interface_type_extension_start : seq<extend_keyword, plus<ignored>, inter
10851092
{
10861093
};
10871094

1095+
struct interface_type_extension_implements_interfaces : seq<plus<ignored>, implements_interfaces>
1096+
{
1097+
};
1098+
1099+
struct interface_type_extension_directives : seq<star<ignored>, directives>
1100+
{
1101+
};
1102+
1103+
struct interface_type_extension_fields_definition : seq<star<ignored>, fields_definition>
1104+
{
1105+
};
1106+
10881107
struct interface_type_extension_content
10891108
: seq<plus<ignored>, interface_name, star<ignored>,
1090-
sor<seq<opt<directives, star<ignored>>, fields_definition>, directives>>
1109+
sor<seq<opt<interface_type_extension_implements_interfaces>,
1110+
opt<interface_type_extension_directives>,
1111+
interface_type_extension_fields_definition>,
1112+
seq<opt<interface_type_extension_implements_interfaces>,
1113+
interface_type_extension_directives>,
1114+
interface_type_extension_implements_interfaces>>
10911115
{
10921116
};
10931117

include/graphqlservice/internal/Schema.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ class InterfaceType : public BaseType
178178
std::string_view name, std::string_view description);
179179

180180
GRAPHQLSERVICE_EXPORT void AddPossibleType(std::weak_ptr<ObjectType> possibleType);
181+
GRAPHQLSERVICE_EXPORT void AddInterfaces(
182+
std::vector<std::shared_ptr<const InterfaceType>>&& interfaces);
181183
GRAPHQLSERVICE_EXPORT void AddFields(std::vector<std::shared_ptr<const Field>>&& fields);
182184

183185
// Accessors
@@ -190,6 +192,7 @@ class InterfaceType : public BaseType
190192
private:
191193
const std::string_view _name;
192194

195+
std::vector<std::shared_ptr<const InterfaceType>> _interfaces;
193196
std::vector<std::shared_ptr<const Field>> _fields;
194197
std::vector<std::weak_ptr<const BaseType>> _possibleTypes;
195198
};

src/Schema.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ void InterfaceType::AddPossibleType(std::weak_ptr<ObjectType> possibleType)
283283
_possibleTypes.push_back(possibleType);
284284
}
285285

286+
void InterfaceType::AddInterfaces(std::vector<std::shared_ptr<const InterfaceType>>&& interfaces)
287+
{
288+
_interfaces = std::move(interfaces);
289+
}
290+
286291
void InterfaceType::AddFields(std::vector<std::shared_ptr<const Field>>&& fields)
287292
{
288293
_fields = std::move(fields);

src/SchemaGenerator.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,6 +1824,7 @@ void )cpp" << cppType
18241824
void Generator::outputInterfaceIntrospection(
18251825
std::ostream& sourceFile, const InterfaceType& interfaceType) const
18261826
{
1827+
outputIntrospectionInterfaces(sourceFile, interfaceType.cppType, interfaceType.interfaces);
18271828
outputIntrospectionFields(sourceFile, interfaceType.cppType, interfaceType.fields);
18281829
}
18291830

@@ -2170,14 +2171,21 @@ service::AwaitableResolver )cpp"
21702171
void Generator::outputObjectIntrospection(
21712172
std::ostream& sourceFile, const ObjectType& objectType) const
21722173
{
2173-
if (!objectType.interfaces.empty())
2174+
outputIntrospectionInterfaces(sourceFile, objectType.cppType, objectType.interfaces);
2175+
outputIntrospectionFields(sourceFile, objectType.cppType, objectType.fields);
2176+
}
2177+
2178+
void Generator::outputIntrospectionInterfaces(std::ostream& sourceFile, std::string_view cppType,
2179+
const std::vector<std::string_view>& interfaces) const
2180+
{
2181+
if (!interfaces.empty())
21742182
{
21752183
bool firstInterface = true;
21762184

2177-
sourceFile << R"cpp( type)cpp" << objectType.cppType << R"cpp(->AddInterfaces({
2185+
sourceFile << R"cpp( type)cpp" << cppType << R"cpp(->AddInterfaces({
21782186
)cpp";
21792187

2180-
for (const auto& interfaceName : objectType.interfaces)
2188+
for (const auto& interfaceName : interfaces)
21812189
{
21822190
if (!firstInterface)
21832191
{
@@ -2196,8 +2204,6 @@ void Generator::outputObjectIntrospection(
21962204
});
21972205
)cpp";
21982206
}
2199-
2200-
outputIntrospectionFields(sourceFile, objectType.cppType, objectType.fields);
22012207
}
22022208

22032209
void Generator::outputIntrospectionFields(

src/SchemaLoader.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,18 @@ void SchemaLoader::visitObjectTypeExtension(const peg::ast_node& objectTypeExten
609609
objectType.fields.push_back(std::move(field));
610610
}
611611
});
612+
613+
if (!_isIntrospection)
614+
{
615+
for (const auto& field : objectType.fields)
616+
{
617+
blockReservedName(field.name, field.position);
618+
for (const auto& argument : field.arguments)
619+
{
620+
blockReservedName(argument.name, argument.position);
621+
}
622+
}
623+
}
612624
}
613625
}
614626

@@ -640,7 +652,7 @@ void SchemaLoader::visitInterfaceTypeDefinition(const peg::ast_node& interfaceTy
640652

641653
auto cppName = getSafeCppName(name);
642654

643-
_interfaceTypes.push_back({ name, cppName, {}, description });
655+
_interfaceTypes.push_back({ name, cppName, {}, {}, description });
644656

645657
visitInterfaceTypeExtension(interfaceTypeDefinition);
646658
}
@@ -664,6 +676,11 @@ void SchemaLoader::visitInterfaceTypeExtension(const peg::ast_node& interfaceTyp
664676
{
665677
auto& interfaceType = _interfaceTypes[itrType->second];
666678

679+
peg::for_each_child<peg::interface_type>(interfaceTypeExtension,
680+
[&interfaceType](const peg::ast_node& child) {
681+
interfaceType.interfaces.push_back(child.string_view());
682+
});
683+
667684
peg::on_first_child<peg::fields_definition>(interfaceTypeExtension,
668685
[&interfaceType](const peg::ast_node& child) {
669686
auto fields = getOutputFields(child.children);
@@ -674,6 +691,18 @@ void SchemaLoader::visitInterfaceTypeExtension(const peg::ast_node& interfaceTyp
674691
interfaceType.fields.push_back(std::move(field));
675692
}
676693
});
694+
695+
if (!_isIntrospection)
696+
{
697+
for (const auto& field : interfaceType.fields)
698+
{
699+
blockReservedName(field.name, field.position);
700+
for (const auto& argument : field.arguments)
701+
{
702+
blockReservedName(argument.name, argument.position);
703+
}
704+
}
705+
}
677706
}
678707
}
679708

@@ -739,6 +768,14 @@ void SchemaLoader::visitInputObjectTypeExtension(const peg::ast_node& inputObjec
739768
inputType.fields.push_back(std::move(field));
740769
}
741770
});
771+
772+
if (!_isIntrospection)
773+
{
774+
for (const auto& field : inputType.fields)
775+
{
776+
blockReservedName(field.name, field.position);
777+
}
778+
}
742779
}
743780
}
744781

@@ -1039,12 +1076,16 @@ void SchemaLoader::visitDirectiveDefinition(const peg::ast_node& directiveDefini
10391076
});
10401077

10411078
peg::on_first_child<peg::arguments_definition>(directiveDefinition,
1042-
[&directive](const peg::ast_node& child) {
1079+
[isIntrospection = _isIntrospection, &directive](const peg::ast_node& child) {
10431080
auto fields = getInputFields(child.children);
10441081

10451082
directive.arguments.reserve(directive.arguments.size() + fields.size());
10461083
for (auto& field : fields)
10471084
{
1085+
if (!isIntrospection)
1086+
{
1087+
blockReservedName(field.name, field.position);
1088+
}
10481089
directive.arguments.push_back(std::move(field));
10491090
}
10501091
});

0 commit comments

Comments
 (0)