Skip to content

Commit ed3f653

Browse files
authored
Merge pull request #7 from Microsoft/preserveinput
Keep the parse_tree input alive so the string pointers remain valid
2 parents 357477a + 0e667cf commit ed3f653

File tree

6 files changed

+51
-33
lines changed

6 files changed

+51
-33
lines changed

GraphQLService.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,9 @@ Request::Request(TypeMap&& operationTypes)
381381

382382
rapidjson::Document Request::resolve(const peg::ast_node& root, const std::string& operationName, const rapidjson::Document::ConstObject& variables) const
383383
{
384-
const auto& document = *root.children.front();
385384
FragmentDefinitionVisitor fragmentVisitor;
386385

387-
peg::for_each_child<peg::fragment_definition>(document,
386+
peg::for_each_child<peg::fragment_definition>(root,
388387
[&fragmentVisitor](const peg::ast_node& child)
389388
{
390389
fragmentVisitor.visit(child);
@@ -393,7 +392,7 @@ rapidjson::Document Request::resolve(const peg::ast_node& root, const std::strin
393392
auto fragments = fragmentVisitor.getFragments();
394393
OperationDefinitionVisitor operationVisitor(_operations, operationName, variables, fragments);
395394

396-
peg::for_each_child<peg::operation_definition>(document,
395+
peg::for_each_child<peg::operation_definition>(root,
397396
[&operationVisitor](const peg::ast_node& child)
398397
{
399398
operationVisitor.visit(child);

GraphQLTree.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -552,27 +552,38 @@ struct ast_selector<input_object_type_extension>
552552
{
553553
};
554554

555-
template <>
556-
struct ast_selector<document>
557-
: std::true_type
555+
std::unique_ptr<ast<std::string>> parseString(std::string&& input)
558556
{
559-
};
557+
std::unique_ptr<ast<std::string>> result(new ast<std::string> { std::move(input), nullptr });
558+
memory_input<> in(result->input.c_str(), result->input.size(), "GraphQL");
560559

561-
std::unique_ptr<ast_node> parseString(const char* text)
562-
{
563-
return parse_tree::parse<document, ast_node, ast_selector>(memory_input<>(text, "GraphQL"));
560+
result->root = parse_tree::parse<document, ast_node, ast_selector>(std::move(in));
561+
562+
return result;
564563
}
565564

566-
std::unique_ptr<ast_node> parseFile(file_input<>&& in)
565+
std::unique_ptr<ast<std::unique_ptr<file_input<>>>> parseFile(const char* filename)
567566
{
568-
return parse_tree::parse<document, ast_node, ast_selector>(std::move(in));
567+
std::unique_ptr<ast<std::unique_ptr<file_input<>>>> result(new ast<std::unique_ptr<file_input<>>> {
568+
std::unique_ptr<file_input<>>(new file_input<>(std::string(filename))),
569+
nullptr
570+
});
571+
572+
result->root = parse_tree::parse<document, ast_node, ast_selector>(std::move(*result->input));
573+
574+
return result;
569575
}
570576

571577
} /* namespace peg */
572578

573-
std::unique_ptr<peg::ast_node> operator "" _graphql(const char* text, size_t size)
579+
std::unique_ptr<peg::ast<const char*>> operator "" _graphql(const char* text, size_t size)
574580
{
575-
return tao::graphqlpeg::parse_tree::parse<peg::document, peg::ast_node, peg::ast_selector>(tao::graphqlpeg::memory_input<>(text, size, "GraphQL"));
581+
std::unique_ptr<peg::ast<const char*>> result(new peg::ast<const char*> { text, nullptr });
582+
peg::memory_input<> in(text, size, "GraphQL");
583+
584+
result->root = peg::parse_tree::parse<peg::document, peg::ast_node, peg::ast_selector>(std::move(in));
585+
586+
return result;
576587
}
577588

578589
} /* namespace graphql */

GraphQLTree.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,19 @@ struct ast_node
2323
std::string unescaped;
2424
};
2525

26-
std::unique_ptr<ast_node> parseString(const char* text);
27-
std::unique_ptr<ast_node> parseFile(file_input<>&& in);
26+
template <typename _Input>
27+
struct ast
28+
{
29+
_Input input;
30+
std::unique_ptr<ast_node> root;
31+
};
32+
33+
std::unique_ptr<ast<std::string>> parseString(std::string&& input);
34+
std::unique_ptr<ast<std::unique_ptr<file_input<>>>> parseFile(const char* filename);
2835

2936
} /* namespace peg */
3037

31-
std::unique_ptr<peg::ast_node> operator "" _graphql(const char* text, size_t size);
38+
std::unique_ptr<peg::ast<const char*>> operator "" _graphql(const char* text, size_t size);
3239

3340
} /* namespace graphql */
3441
} /* namespace facebook */

SchemaGenerator.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ Generator::Generator()
144144
throw std::logic_error("Unable to parse the introspection schema, but there was no error message from the parser!");
145145
}
146146

147-
for (const auto& child : ast->children.front()->children)
147+
for (const auto& child : ast->root->children)
148148
{
149149
visitDefinition(*child);
150150
}
@@ -160,15 +160,14 @@ Generator::Generator(std::string schemaFileName, std::string filenamePrefix, std
160160
, _filenamePrefix(std::move(filenamePrefix))
161161
, _schemaNamespace(std::move(schemaNamespace))
162162
{
163-
tao::graphqlpeg::file_input<> in(schemaFileName.c_str());
164-
auto ast = peg::parseFile(std::move(in));
163+
auto ast = peg::parseFile(schemaFileName.c_str());
165164

166165
if (!ast)
167166
{
168167
throw std::logic_error("Unable to parse the service schema, but there was no error message from the parser!");
169168
}
170169

171-
for (const auto& child : ast->children.front()->children)
170+
for (const auto& child : ast->root->children)
172171
{
173172
visitDefinition(*child);
174173
}

test_today.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,27 @@ int main(int argc, char** argv)
6060

6161
try
6262
{
63-
std::string input;
64-
std::unique_ptr<tao::graphqlpeg::file_input<>> file;
65-
std::unique_ptr<peg::ast_node> ast;
63+
const peg::ast_node* ast = nullptr;
64+
std::unique_ptr<peg::ast<std::string>> ast_input;
65+
std::unique_ptr<peg::ast<std::unique_ptr<peg::file_input<>>>> ast_file;
6666

6767
if (argc > 1)
6868
{
69-
file.reset(new tao::graphqlpeg::file_input<>(argv[1]));
70-
ast = peg::parseFile(std::move(*file));
69+
ast_file = peg::parseFile(argv[1]);
70+
ast = ast_file->root.get();
7171
}
7272
else
7373
{
74+
std::string input;
7475
std::string line;
7576

7677
while (std::getline(std::cin, line))
7778
{
7879
input.append(line);
7980
}
8081

81-
ast = peg::parseString(input.c_str());
82+
ast_input = peg::parseString(std::move(input));
83+
ast = ast_input->root.get();
8284
}
8385

8486
if (!ast)

tests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ TEST_F(TodayServiceCase, QueryEverything)
123123
}
124124
})"_graphql;
125125
const rapidjson::Document variables(rapidjson::Type::kObjectType);
126-
const auto result = _service->resolve(*ast, "Everything", variables.GetObject());
126+
const auto result = _service->resolve(*ast->root, "Everything", variables.GetObject());
127127
EXPECT_EQ(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
128128
EXPECT_EQ(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
129129
EXPECT_EQ(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -197,7 +197,7 @@ TEST_F(TodayServiceCase, QueryAppointments)
197197
}
198198
})"_graphql;
199199
const rapidjson::Document variables(rapidjson::Type::kObjectType);
200-
const auto result = _service->resolve(*ast, "", variables.GetObject());
200+
const auto result = _service->resolve(*ast->root, "", variables.GetObject());
201201
EXPECT_EQ(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
202202
EXPECT_GE(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
203203
EXPECT_GE(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -252,7 +252,7 @@ TEST_F(TodayServiceCase, QueryTasks)
252252
}
253253
})gql"_graphql;
254254
const rapidjson::Document variables(rapidjson::Type::kObjectType);
255-
const auto result = _service->resolve(*ast, "", variables.GetObject());
255+
const auto result = _service->resolve(*ast->root, "", variables.GetObject());
256256
EXPECT_GE(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
257257
EXPECT_EQ(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
258258
EXPECT_GE(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -306,7 +306,7 @@ TEST_F(TodayServiceCase, QueryUnreadCounts)
306306
}
307307
})"_graphql;
308308
const rapidjson::Document variables(rapidjson::Type::kObjectType);
309-
const auto result = _service->resolve(*ast, "", variables.GetObject());
309+
const auto result = _service->resolve(*ast->root, "", variables.GetObject());
310310
EXPECT_GE(size_t(1), _getAppointmentsCount) << "today service lazy loads the appointments and caches the result";
311311
EXPECT_GE(size_t(1), _getTasksCount) << "today service lazy loads the tasks and caches the result";
312312
EXPECT_EQ(size_t(1), _getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result";
@@ -359,7 +359,7 @@ TEST_F(TodayServiceCase, MutateCompleteTask)
359359
}
360360
})"_graphql;
361361
const rapidjson::Document variables(rapidjson::Type::kObjectType);
362-
const auto result = _service->resolve(*ast, "", variables.GetObject());
362+
const auto result = _service->resolve(*ast->root, "", variables.GetObject());
363363

364364
try
365365
{
@@ -434,7 +434,7 @@ TEST_F(TodayServiceCase, Introspection)
434434
}
435435
})"_graphql;
436436
const rapidjson::Document variables(rapidjson::Type::kObjectType);
437-
const auto result = _service->resolve(*ast, "", variables.GetObject());
437+
const auto result = _service->resolve(*ast->root, "", variables.GetObject());
438438

439439
try
440440
{

0 commit comments

Comments
 (0)