@@ -358,7 +358,6 @@ rapidjson::Document Request::resolve(const peg::ast_node& root, const std::strin
358
358
[&fragmentVisitor](const peg::ast_node& child)
359
359
{
360
360
fragmentVisitor.visit (child);
361
- return true ;
362
361
});
363
362
364
363
auto fragments = fragmentVisitor.getFragments ();
@@ -368,7 +367,6 @@ rapidjson::Document Request::resolve(const peg::ast_node& root, const std::strin
368
367
[&operationVisitor](const peg::ast_node& child)
369
368
{
370
369
operationVisitor.visit (child);
371
- return true ;
372
370
});
373
371
374
372
return operationVisitor.getValue ();
@@ -406,10 +404,28 @@ void SelectionVisitor::visit(const peg::ast_node& selection)
406
404
407
405
void SelectionVisitor::visitField (const peg::ast_node& field)
408
406
{
409
- const bool hasAlias = field.children .front ()->is <peg::alias_name>();
410
- const std::string name (field.children [hasAlias ? 1 : 0 ]->content ());
411
- const std::string alias (hasAlias ? field.children .front ()->content () : name);
412
- auto itr = _resolvers.find (name);
407
+ std::string name;
408
+
409
+ peg::on_first_child<peg::field_name>(field,
410
+ [&name](const peg::ast_node& child)
411
+ {
412
+ name = child.content ();
413
+ });
414
+
415
+ std::string alias;
416
+
417
+ peg::on_first_child<peg::alias_name>(field,
418
+ [&alias](const peg::ast_node& child)
419
+ {
420
+ alias = child.content ();
421
+ });
422
+
423
+ if (alias.empty ())
424
+ {
425
+ alias = name;
426
+ }
427
+
428
+ const auto itr = _resolvers.find (name);
413
429
414
430
if (itr == _resolvers.cend ())
415
431
{
@@ -425,11 +441,10 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
425
441
426
442
bool skip = false ;
427
443
428
- peg::for_each_child <peg::directives>(field,
444
+ peg::on_first_child <peg::directives>(field,
429
445
[this , &skip](const peg::ast_node& child)
430
446
{
431
447
skip = shouldSkip (&child.children );
432
- return false ;
433
448
});
434
449
435
450
if (skip)
@@ -439,7 +454,7 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
439
454
440
455
rapidjson::Document arguments (rapidjson::Type::kObjectType );
441
456
442
- peg::for_each_child <peg::arguments>(field,
457
+ peg::on_first_child <peg::arguments>(field,
443
458
[this , &arguments](const peg::ast_node& child)
444
459
{
445
460
ValueVisitor visitor (_variables);
@@ -454,17 +469,14 @@ void SelectionVisitor::visitField(const peg::ast_node& field)
454
469
argumentValue.CopyFrom (visitor.getValue (), argumentAllocator);
455
470
arguments.AddMember (argumentName, argumentValue, argumentAllocator);
456
471
}
457
-
458
- return false ;
459
472
});
460
473
461
474
const peg::ast_node* selection = nullptr ;
462
475
463
- peg::for_each_child <peg::selection_set>(field,
476
+ peg::on_first_child <peg::selection_set>(field,
464
477
[&selection](const peg::ast_node& child)
465
478
{
466
479
selection = &child;
467
- return false ;;
468
480
});
469
481
470
482
auto & selectionAllocator = _values.GetAllocator ();
@@ -497,11 +509,10 @@ void SelectionVisitor::visitFragmentSpread(const peg::ast_node& fragmentSpread)
497
509
498
510
if (!skip)
499
511
{
500
- peg::for_each_child <peg::directives>(fragmentSpread,
512
+ peg::on_first_child <peg::directives>(fragmentSpread,
501
513
[this , &skip](const peg::ast_node& child)
502
514
{
503
515
skip = shouldSkip (&child.children );
504
- return false ;
505
516
});
506
517
}
507
518
@@ -510,26 +521,24 @@ void SelectionVisitor::visitFragmentSpread(const peg::ast_node& fragmentSpread)
510
521
return ;
511
522
}
512
523
513
- peg::for_each_child <peg::selection_set>(fragmentSpread,
524
+ peg::on_first_child <peg::selection_set>(fragmentSpread,
514
525
[this ](const peg::ast_node& child)
515
526
{
516
527
for (const auto & selection : child.children )
517
528
{
518
529
visit (*selection);
519
530
}
520
- return false ;
521
531
});
522
532
}
523
533
524
534
void SelectionVisitor::visitInlineFragment (const peg::ast_node& inlineFragment)
525
535
{
526
536
bool skip = false ;
527
537
528
- peg::for_each_child <peg::directives>(inlineFragment,
538
+ peg::on_first_child <peg::directives>(inlineFragment,
529
539
[this , &skip](const peg::ast_node& child)
530
540
{
531
541
skip = shouldSkip (&child.children );
532
- return false ;
533
542
});
534
543
535
544
if (skip)
@@ -539,41 +548,23 @@ void SelectionVisitor::visitInlineFragment(const peg::ast_node& inlineFragment)
539
548
540
549
const peg::ast_node* typeCondition = nullptr ;
541
550
542
- for (const auto & child : inlineFragment.children )
551
+ peg::on_first_child<peg::type_condition>(inlineFragment,
552
+ [&typeCondition](const peg::ast_node& child)
543
553
{
544
- if (child->is <peg::type_condition>())
545
- {
546
- typeCondition = child.get ();
547
- break ;
548
- }
549
- }
554
+ typeCondition = &child;
555
+ });
550
556
551
557
if (typeCondition == nullptr
552
558
|| _typeNames.count (typeCondition->children .front ()->content ()) > 0 )
553
559
{
554
- for (const auto & child : inlineFragment.children )
560
+ peg::on_first_child<peg::selection_set>(inlineFragment,
561
+ [this ](const peg::ast_node& child)
555
562
{
556
- if (child-> is <peg::selection_set>() )
563
+ for ( const auto & selection : child. children )
557
564
{
558
- for (const auto & selection : child->children )
559
- {
560
- if (selection->is <peg::field>())
561
- {
562
- visitField (*selection);
563
- }
564
- else if (selection->is <peg::fragment_spread>())
565
- {
566
- visitFragmentSpread (*selection);
567
- }
568
- else if (selection->is <peg::inline_fragment>())
569
- {
570
- visitInlineFragment (*selection);
571
- }
572
- }
573
-
574
- break ;
565
+ visit (*selection);
575
566
}
576
- }
567
+ });
577
568
}
578
569
}
579
570
@@ -586,7 +577,14 @@ bool SelectionVisitor::shouldSkip(const std::vector<std::unique_ptr<peg::ast_nod
586
577
587
578
for (const auto & directive : *directives)
588
579
{
589
- const std::string name (directive->children .front ()->content ());
580
+ std::string name;
581
+
582
+ peg::on_first_child<peg::directive_name>(*directive,
583
+ [&name](const peg::ast_node& child)
584
+ {
585
+ name = child.content ();
586
+ });
587
+
590
588
const bool include = (name == " include" );
591
589
const bool skip = (!include && (name == " skip" ));
592
590
@@ -595,10 +593,40 @@ bool SelectionVisitor::shouldSkip(const std::vector<std::unique_ptr<peg::ast_nod
595
593
continue ;
596
594
}
597
595
598
- const auto argument = (directive->children .back ()->is <peg::arguments>() && directive->children .back ()->children .size () == 1 )
599
- ? directive->children .back ()->children .front ().get ()
600
- : nullptr ;
601
- const std::string argumentName ((argument != nullptr ) ? argument->children .front ()->content () : " " );
596
+ peg::ast_node* argument = nullptr ;
597
+ std::string argumentName;
598
+ bool argumentTrue = false ;
599
+ bool argumentFalse = false ;
600
+
601
+ peg::on_first_child<peg::arguments>(*directive,
602
+ [&argument, &argumentName, &argumentTrue, &argumentFalse](const peg::ast_node& child)
603
+ {
604
+ if (child.children .size () == 1 )
605
+ {
606
+ argument = child.children .front ().get ();
607
+
608
+ peg::on_first_child<peg::argument_name>(*argument,
609
+ [&argumentName](const peg::ast_node& nameArg)
610
+ {
611
+ argumentName = nameArg.content ();
612
+ });
613
+
614
+ peg::on_first_child<peg::true_keyword>(*argument,
615
+ [&argumentTrue](const peg::ast_node& nameArg)
616
+ {
617
+ argumentTrue = true ;
618
+ });
619
+
620
+ if (!argumentTrue)
621
+ {
622
+ peg::on_first_child<peg::false_keyword>(*argument,
623
+ [&argumentFalse](const peg::ast_node& nameArg)
624
+ {
625
+ argumentFalse = true ;
626
+ });
627
+ }
628
+ }
629
+ });
602
630
603
631
if (argumentName != " if" )
604
632
{
@@ -622,11 +650,11 @@ bool SelectionVisitor::shouldSkip(const std::vector<std::unique_ptr<peg::ast_nod
622
650
throw schema_exception ({ error.str () });
623
651
}
624
652
625
- if (argument-> children . back ()-> is <peg::true_keyword>() )
653
+ if (argumentTrue )
626
654
{
627
655
return skip;
628
656
}
629
- else if (argument-> children . back ()-> is <peg::false_keyword>() )
657
+ else if (argumentFalse )
630
658
{
631
659
return !skip;
632
660
}
@@ -843,17 +871,26 @@ rapidjson::Document OperationDefinitionVisitor::getValue()
843
871
844
872
void OperationDefinitionVisitor::visit (const peg::ast_node& operationDefinition)
845
873
{
874
+ std::string operation;
875
+
876
+ peg::on_first_child<peg::operation_type>(operationDefinition,
877
+ [&operation](const peg::ast_node& child)
878
+ {
879
+ operation = child.content ();
880
+ });
881
+
882
+ if (operation.empty ())
883
+ {
884
+ operation = " query" ;
885
+ }
886
+
846
887
auto position = operationDefinition.begin ();
847
- auto operation = operationDefinition.children .front ()->is <peg::operation_type>()
848
- ? operationDefinition.children .front ()->content ()
849
- : std::string (" query" );
850
888
std::string name;
851
889
852
- peg::for_each_child <peg::operation_name>(operationDefinition,
890
+ peg::on_first_child <peg::operation_name>(operationDefinition,
853
891
[&name](const peg::ast_node& child)
854
892
{
855
893
name = child.content ();
856
- return false ;
857
894
});
858
895
859
896
if (!_operationName.empty ()
@@ -910,35 +947,44 @@ void OperationDefinitionVisitor::visit(const peg::ast_node& operationDefinition)
910
947
911
948
auto operationVariables = rapidjson::Document (rapidjson::Type::kObjectType );
912
949
913
- peg::for_each_child <peg::variable_definitions>(operationDefinition,
950
+ peg::on_first_child <peg::variable_definitions>(operationDefinition,
914
951
[this , &operationVariables](const peg::ast_node& child)
915
952
{
916
- auto & variableAllocator = operationVariables.GetAllocator ();
917
-
918
- for (const auto & variable : child.children )
953
+ peg::for_each_child<peg::variable>(child,
954
+ [this , &operationVariables](const peg::ast_node& variable)
919
955
{
920
- const auto & nameNode = *variable->children .front ();
921
- const auto & defaultValueNode = *variable->children .back ();
922
- rapidjson::Value nameVar (nameNode.content ().c_str () + 1 , variableAllocator);
923
- rapidjson::Value valueVar;
956
+ std::string variableName;
957
+
958
+ peg::on_first_child<peg::variable_name>(variable,
959
+ [&variableName](const peg::ast_node& name)
960
+ {
961
+ // Skip the $ prefix
962
+ variableName = name.content ().c_str () + 1 ;
963
+ });
964
+
965
+ rapidjson::Value nameVar (rapidjson::StringRef (variableName.c_str ()));
924
966
auto itrVar = _variables.FindMember (nameVar);
967
+ auto & variableAllocator = operationVariables.GetAllocator ();
968
+ rapidjson::Value valueVar;
925
969
926
970
if (itrVar != _variables.MemberEnd ())
927
971
{
928
972
valueVar.CopyFrom (itrVar->value , variableAllocator);
929
973
}
930
- else if (defaultValueNode. is <peg::default_value>())
974
+ else
931
975
{
932
- ValueVisitor visitor (_variables);
976
+ peg::on_first_child<peg::default_value>(variable,
977
+ [this , &variableAllocator, &valueVar](const peg::ast_node& defaultValue)
978
+ {
979
+ ValueVisitor visitor (_variables);
933
980
934
- visitor.visit (*defaultValueNode.children .front ());
935
- valueVar.CopyFrom (visitor.getValue (), variableAllocator);
981
+ visitor.visit (*defaultValue.children .front ());
982
+ valueVar.CopyFrom (visitor.getValue (), variableAllocator);
983
+ });
936
984
}
937
985
938
986
operationVariables.AddMember (nameVar, valueVar, variableAllocator);
939
- }
940
-
941
- return false ;
987
+ });
942
988
});
943
989
944
990
_result = rapidjson::Document (rapidjson::Type::kObjectType );
0 commit comments