From 03dd0b48692dd11c9bc98f58dd8ca43ba5b2bdab Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Sat, 6 Nov 2021 23:07:18 +0300 Subject: [PATCH 1/4] Descriptions rework --- .github/workflows/test.yml | 2 +- src/Directory.Build.props | 4 +- .../GraphQL-Parser.approved.txt | 42 ++--- .../Benchmarks/ParserBenchmark.cs | 42 +++-- .../GraphQLAstVisitorTests.cs | 138 ++++++++------ .../Issue2478_GraphQL_NET.cs | 5 +- src/GraphQLParser.Tests/Issue82.cs | 5 +- src/GraphQLParser.Tests/ParserTests.cs | 175 ++++++++++++------ .../Validation/ParserValidationTests.cs | 40 ++-- src/GraphQLParser/AST/ASTNodeKind.cs | 2 +- src/GraphQLParser/AST/GraphQLComment.cs | 18 +- src/GraphQLParser/AST/GraphQLDescription.cs | 4 + .../AST/GraphQLDirectiveDefinition.cs | 2 +- .../AST/GraphQLEnumTypeDefinition.cs | 2 +- .../AST/GraphQLEnumValueDefinition.cs | 2 +- .../AST/GraphQLFieldDefinition.cs | 2 +- .../AST/GraphQLInputObjectTypeDefinition.cs | 2 +- .../AST/GraphQLInputValueDefinition.cs | 2 +- .../AST/GraphQLInterfaceTypeDefinition.cs | 2 +- .../AST/GraphQLObjectTypeDefinition.cs | 2 +- .../AST/GraphQLScalarTypeDefinition.cs | 2 +- .../AST/GraphQLSchemaDefinition.cs | 5 +- .../AST/GraphQLTypeDefinition.cs | 9 +- .../AST/GraphQLUnionTypeDefinition.cs | 2 +- src/GraphQLParser/AST/IHasDescription.cs | 7 - src/GraphQLParser/AST/IHasDescriptionNode.cs | 14 ++ src/GraphQLParser/IgnoreOptions.cs | 18 +- src/GraphQLParser/ParserContext.Parse.cs | 119 ++++++------ 28 files changed, 405 insertions(+), 264 deletions(-) delete mode 100644 src/GraphQLParser/AST/IHasDescription.cs create mode 100644 src/GraphQLParser/AST/IHasDescriptionNode.cs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 79e0079a..683d9886 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: - name: Setup .NET Core 5.0 SDK uses: actions/setup-dotnet@v1 with: - dotnet-version: '5.0.201' + dotnet-version: '5.0.x' source-url: https://nuget.pkg.github.com/graphql-dotnet/index.json env: NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/src/Directory.Build.props b/src/Directory.Build.props index f82dbc2d..0f68b091 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,8 +1,8 @@ - 7.2.0-preview - 8.0 + 8.0.0-preview + 9.0 true true true diff --git a/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt b/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt index 6f308433..132fd9b9 100644 --- a/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt +++ b/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt @@ -61,7 +61,6 @@ namespace GraphQLParser.AST public GraphQLComment() { } public override GraphQLParser.AST.ASTNodeKind Kind { get; } public GraphQLParser.ROM Text { get; set; } - public override GraphQLParser.AST.GraphQLLocation Location { get; set; } } public class GraphQLDescription : GraphQLParser.AST.ASTNode { @@ -76,7 +75,7 @@ namespace GraphQLParser.AST public override GraphQLParser.AST.ASTNodeKind Kind { get; } public GraphQLParser.AST.GraphQLName? Name { get; set; } } - public class GraphQLDirectiveDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription + public class GraphQLDirectiveDefinition : GraphQLParser.AST.GraphQLTypeDefinition { public GraphQLDirectiveDefinition() { } public System.Collections.Generic.List? Arguments { get; set; } @@ -93,20 +92,20 @@ namespace GraphQLParser.AST public void Dispose() { } protected virtual void Dispose(bool disposing) { } } - public class GraphQLEnumTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLEnumTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLEnumTypeDefinition() { } public System.Collections.Generic.List? Directives { get; set; } public override GraphQLParser.AST.ASTNodeKind Kind { get; } public System.Collections.Generic.List? Values { get; set; } } - public class GraphQLEnumValueDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLEnumValueDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLEnumValueDefinition() { } public System.Collections.Generic.List? Directives { get; set; } public override GraphQLParser.AST.ASTNodeKind Kind { get; } } - public class GraphQLFieldDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLFieldDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLFieldDefinition() { } public System.Collections.Generic.List? Arguments { get; set; } @@ -145,14 +144,14 @@ namespace GraphQLParser.AST public GraphQLParser.AST.GraphQLSelectionSet? SelectionSet { get; set; } public GraphQLParser.AST.GraphQLNamedType? TypeCondition { get; set; } } - public class GraphQLInputObjectTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLInputObjectTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLInputObjectTypeDefinition() { } public System.Collections.Generic.List? Directives { get; set; } public System.Collections.Generic.List? Fields { get; set; } public override GraphQLParser.AST.ASTNodeKind Kind { get; } } - public class GraphQLInputValueDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLInputValueDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLInputValueDefinition() { } public GraphQLParser.AST.GraphQLValue? DefaultValue { get; set; } @@ -160,7 +159,7 @@ namespace GraphQLParser.AST public override GraphQLParser.AST.ASTNodeKind Kind { get; } public GraphQLParser.AST.GraphQLType? Type { get; set; } } - public class GraphQLInterfaceTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLInterfaceTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLInterfaceTypeDefinition() { } public System.Collections.Generic.List? Directives { get; set; } @@ -221,7 +220,7 @@ namespace GraphQLParser.AST public GraphQLParser.AST.GraphQLName? Name { get; set; } public GraphQLParser.AST.GraphQLValue? Value { get; set; } } - public class GraphQLObjectTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLObjectTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLObjectTypeDefinition() { } public System.Collections.Generic.List? Directives { get; set; } @@ -252,7 +251,7 @@ namespace GraphQLParser.AST public GraphQLParser.AST.OperationType Operation { get; set; } public GraphQLParser.AST.GraphQLNamedType? Type { get; set; } } - public class GraphQLScalarTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLScalarTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLScalarTypeDefinition() { } public System.Collections.Generic.List? Directives { get; set; } @@ -265,9 +264,10 @@ namespace GraphQLParser.AST public GraphQLParser.ROM Value { get; set; } public override string? ToString() { } } - public class GraphQLSchemaDefinition : GraphQLParser.AST.ASTNode, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLSchemaDefinition : GraphQLParser.AST.ASTNode, GraphQLParser.AST.IHasDescriptionNode, GraphQLParser.AST.IHasDirectivesNode { public GraphQLSchemaDefinition() { } + public GraphQLParser.AST.GraphQLDescription? Description { get; set; } public System.Collections.Generic.List? Directives { get; set; } public override GraphQLParser.AST.ASTNodeKind Kind { get; } public System.Collections.Generic.List? OperationTypes { get; set; } @@ -282,15 +282,11 @@ namespace GraphQLParser.AST { protected GraphQLType() { } } - public abstract class GraphQLTypeDefinition : GraphQLParser.AST.ASTNode, GraphQLParser.AST.INamedNode + public abstract class GraphQLTypeDefinition : GraphQLParser.AST.ASTNode, GraphQLParser.AST.IHasDescriptionNode, GraphQLParser.AST.INamedNode { protected GraphQLTypeDefinition() { } - public GraphQLParser.AST.GraphQLName? Name { get; set; } - } - public abstract class GraphQLTypeDefinitionWithDescription : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDescription - { - protected GraphQLTypeDefinitionWithDescription() { } public GraphQLParser.AST.GraphQLDescription? Description { get; set; } + public GraphQLParser.AST.GraphQLName? Name { get; set; } } public class GraphQLTypeExtensionDefinition : GraphQLParser.AST.GraphQLTypeDefinition { @@ -298,7 +294,7 @@ namespace GraphQLParser.AST public GraphQLParser.AST.GraphQLObjectTypeDefinition? Definition { get; set; } public override GraphQLParser.AST.ASTNodeKind Kind { get; } } - public class GraphQLUnionTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinitionWithDescription, GraphQLParser.AST.IHasDirectivesNode + public class GraphQLUnionTypeDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode { public GraphQLUnionTypeDefinition() { } public System.Collections.Generic.List? Directives { get; set; } @@ -323,7 +319,7 @@ namespace GraphQLParser.AST public GraphQLParser.AST.GraphQLType? Type { get; set; } public GraphQLParser.AST.GraphQLVariable? Variable { get; set; } } - public interface IHasDescription + public interface IHasDescriptionNode { GraphQLParser.AST.GraphQLDescription? Description { get; set; } } @@ -390,11 +386,13 @@ namespace GraphQLParser public virtual GraphQLParser.AST.GraphQLVariable EndVisitVariable(GraphQLParser.AST.GraphQLVariable variable) { } public virtual void Visit(GraphQLParser.AST.GraphQLDocument ast) { } } + [System.Flags] public enum IgnoreOptions { - IgnoreComments = 0, - IgnoreCommentsAndLocations = 1, - None = 2, + None = 0, + Comments = 1, + Locations = 2, + All = 3, } public static class Lexer { diff --git a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs index 13f3b837..686c8cb2 100644 --- a/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs +++ b/src/GraphQLParser.Benchmarks/Benchmarks/ParserBenchmark.cs @@ -28,9 +28,10 @@ private class ParserOrderer : IOrderer private static int GetOrder(object o) => o switch { IgnoreOptions.None => 1, - IgnoreOptions.IgnoreComments => 2, - IgnoreOptions.IgnoreCommentsAndLocations => 3, - _ => 4 + IgnoreOptions.Comments => 2, + IgnoreOptions.Locations => 3, + IgnoreOptions.All => 4, + _ => 5 }; public IEnumerable GetExecutionOrder(ImmutableArray benchmarksCase) => benchmarksCase; @@ -62,32 +63,39 @@ public void Parse(string name, IgnoreOptions options) public IEnumerable NamesAndOptions() { yield return new object[] { "hero", IgnoreOptions.None }; - yield return new object[] { "hero", IgnoreOptions.IgnoreComments }; - yield return new object[] { "hero", IgnoreOptions.IgnoreCommentsAndLocations }; + yield return new object[] { "hero", IgnoreOptions.Comments }; + yield return new object[] { "hero", IgnoreOptions.Locations }; + yield return new object[] { "hero", IgnoreOptions.All }; yield return new object[] { "escapes", IgnoreOptions.None }; - yield return new object[] { "escapes", IgnoreOptions.IgnoreComments }; - yield return new object[] { "escapes", IgnoreOptions.IgnoreCommentsAndLocations }; + yield return new object[] { "escapes", IgnoreOptions.Comments }; + yield return new object[] { "escapes", IgnoreOptions.Locations }; + yield return new object[] { "escapes", IgnoreOptions.All }; yield return new object[] { "kitchen", IgnoreOptions.None }; - yield return new object[] { "kitchen", IgnoreOptions.IgnoreComments }; - yield return new object[] { "kitchen", IgnoreOptions.IgnoreCommentsAndLocations }; + yield return new object[] { "kitchen", IgnoreOptions.Comments }; + yield return new object[] { "kitchen", IgnoreOptions.Locations }; + yield return new object[] { "kitchen", IgnoreOptions.All }; yield return new object[] { "introspection", IgnoreOptions.None }; - yield return new object[] { "introspection", IgnoreOptions.IgnoreComments }; - yield return new object[] { "introspection", IgnoreOptions.IgnoreCommentsAndLocations }; + yield return new object[] { "introspection", IgnoreOptions.Comments }; + yield return new object[] { "introspection", IgnoreOptions.Locations }; + yield return new object[] { "introspection", IgnoreOptions.All }; yield return new object[] { "params", IgnoreOptions.None }; - yield return new object[] { "params", IgnoreOptions.IgnoreComments }; - yield return new object[] { "params", IgnoreOptions.IgnoreCommentsAndLocations }; + yield return new object[] { "params", IgnoreOptions.Comments }; + yield return new object[] { "params", IgnoreOptions.Locations }; + yield return new object[] { "params", IgnoreOptions.All }; yield return new object[] { "variables", IgnoreOptions.None }; - yield return new object[] { "variables", IgnoreOptions.IgnoreComments }; - yield return new object[] { "variables", IgnoreOptions.IgnoreCommentsAndLocations }; + yield return new object[] { "variables", IgnoreOptions.Comments }; + yield return new object[] { "variables", IgnoreOptions.Locations }; + yield return new object[] { "variables", IgnoreOptions.All }; yield return new object[] { "github", IgnoreOptions.None }; - yield return new object[] { "github", IgnoreOptions.IgnoreComments }; - yield return new object[] { "github", IgnoreOptions.IgnoreCommentsAndLocations }; + yield return new object[] { "github", IgnoreOptions.Comments }; + yield return new object[] { "github", IgnoreOptions.Locations }; + yield return new object[] { "github", IgnoreOptions.All }; } public override void Run() => Parse("params", IgnoreOptions.None); diff --git a/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs b/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs index d78125e7..6bf56e2e 100644 --- a/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs +++ b/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs @@ -54,8 +54,8 @@ public GraphQLAstVisitorTests() [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.All)] public void Visit_BooleanValueArgument_VisitsOneBooleanValue(IgnoreOptions options) { using var d = "{ stuff(id : true) }".Parse(new ParserOptions { Ignore = options }); @@ -66,8 +66,8 @@ public void Visit_BooleanValueArgument_VisitsOneBooleanValue(IgnoreOptions optio [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.All)] public void Visit_DefinitionWithSingleFragmentSpread_VisitsFragmentSpreadOneTime(IgnoreOptions options) { using var d = "{ foo { ...fragment } }".Parse(new ParserOptions { Ignore = options }); @@ -78,8 +78,9 @@ public void Visit_DefinitionWithSingleFragmentSpread_VisitsFragmentSpreadOneTime [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_DefinitionWithSingleFragmentSpread_VisitsNameOfPropertyAndFragmentSpread(IgnoreOptions options) { using var d = "{ foo { ...fragment } }".Parse(new ParserOptions { Ignore = options }); @@ -90,8 +91,9 @@ public void Visit_DefinitionWithSingleFragmentSpread_VisitsNameOfPropertyAndFrag [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_DirectiveWithVariable_VisitsVariableOnce(IgnoreOptions options) { using var d = "{ ... @include(if : $stuff) { field } }".Parse(new ParserOptions { Ignore = options }); @@ -102,8 +104,9 @@ public void Visit_DirectiveWithVariable_VisitsVariableOnce(IgnoreOptions options [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_EnumValueArgument_VisitsOneEnumValue(IgnoreOptions options) { using var d = "{ stuff(id : TEST_ENUM) }".Parse(new ParserOptions { Ignore = options }); @@ -114,8 +117,9 @@ public void Visit_EnumValueArgument_VisitsOneEnumValue(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_FloatValueArgument_VisitsOneFloatValue(IgnoreOptions options) { using var d = "{ stuff(id : 1.2) }".Parse(new ParserOptions { Ignore = options }); @@ -126,8 +130,9 @@ public void Visit_FloatValueArgument_VisitsOneFloatValue(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_FragmentWithTypeCondition_VisitsFragmentDefinitionOnce(IgnoreOptions options) { using var d = "fragment testFragment on Stuff { field }".Parse(new ParserOptions { Ignore = options }); @@ -138,8 +143,9 @@ public void Visit_FragmentWithTypeCondition_VisitsFragmentDefinitionOnce(IgnoreO [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_FragmentWithTypeCondition_VisitsTypeConditionOnce(IgnoreOptions options) { using var d = "fragment testFragment on Stuff { field }".Parse(new ParserOptions { Ignore = options }); @@ -150,8 +156,9 @@ public void Visit_FragmentWithTypeCondition_VisitsTypeConditionOnce(IgnoreOption [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_InlineFragmentWithDirectiveAndArgument_VisitsArgumentsOnce(IgnoreOptions options) { using var d = "{ ... @include(if : $stuff) { field } }".Parse(new ParserOptions { Ignore = options }); @@ -162,8 +169,9 @@ public void Visit_InlineFragmentWithDirectiveAndArgument_VisitsArgumentsOnce(Ign [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_InlineFragmentWithDirectiveAndArgument_VisitsDirectiveOnce(IgnoreOptions options) { using var d = "{ ... @include(if : $stuff) { field } }".Parse(new ParserOptions { Ignore = options }); @@ -174,8 +182,9 @@ public void Visit_InlineFragmentWithDirectiveAndArgument_VisitsDirectiveOnce(Ign [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_InlineFragmentWithDirectiveAndArgument_VisitsNameThreeTimes(IgnoreOptions options) { using var d = "{ ... @include(if : $stuff) { field } }".Parse(new ParserOptions { Ignore = options }); @@ -186,8 +195,9 @@ public void Visit_InlineFragmentWithDirectiveAndArgument_VisitsNameThreeTimes(Ig [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_InlineFragmentWithOneField_VisitsOneField(IgnoreOptions options) { using var d = "{ ... @include(if : $stuff) { field } }".Parse(new ParserOptions { Ignore = options }); @@ -198,8 +208,9 @@ public void Visit_InlineFragmentWithOneField_VisitsOneField(IgnoreOptions option [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_InlineFragmentWithTypeCondition_VisitsInlineFragmentOnce(IgnoreOptions options) { using var d = "{ ... on Stuff { field } }".Parse(new ParserOptions { Ignore = options }); @@ -210,8 +221,9 @@ public void Visit_InlineFragmentWithTypeCondition_VisitsInlineFragmentOnce(Ignor [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_InlineFragmentWithTypeCondition_VisitsTypeConditionOnce(IgnoreOptions options) { using var d = "{ ... on Stuff { field } }".Parse(new ParserOptions { Ignore = options }); @@ -222,8 +234,9 @@ public void Visit_InlineFragmentWithTypeCondition_VisitsTypeConditionOnce(Ignore [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_IntValueArgument_VisitsOneIntValue(IgnoreOptions options) { using var d = "{ stuff(id : 1) }".Parse(new ParserOptions { Ignore = options }); @@ -234,8 +247,9 @@ public void Visit_IntValueArgument_VisitsOneIntValue(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_OneDefinition_CallsVisitDefinitionOnce(IgnoreOptions options) { using var d = "{ a }".Parse(new ParserOptions { Ignore = options }); @@ -246,8 +260,9 @@ public void Visit_OneDefinition_CallsVisitDefinitionOnce(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_OneDefinition_ProvidesCorrectDefinitionAsParameter(IgnoreOptions options) { using var d = "{ a }".Parse(new ParserOptions { Ignore = options }); @@ -258,8 +273,9 @@ public void Visit_OneDefinition_ProvidesCorrectDefinitionAsParameter(IgnoreOptio [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_OneDefinition_VisitsOneSelectionSet(IgnoreOptions options) { using var d = "{ a, b }".Parse(new ParserOptions { Ignore = options }); @@ -270,8 +286,9 @@ public void Visit_OneDefinition_VisitsOneSelectionSet(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_OneDefinitionWithOneAliasedField_VisitsOneAlias(IgnoreOptions options) { using var d = "{ foo, foo : bar }".Parse(new ParserOptions { Ignore = options }); @@ -282,8 +299,9 @@ public void Visit_OneDefinitionWithOneAliasedField_VisitsOneAlias(IgnoreOptions [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_OneDefinitionWithOneArgument_VisitsOneArgument(IgnoreOptions options) { using var d = "{ foo(id : 1) { name } }".Parse(new ParserOptions { Ignore = options }); @@ -294,8 +312,9 @@ public void Visit_OneDefinitionWithOneArgument_VisitsOneArgument(IgnoreOptions o [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_OneDefinitionWithOneNestedArgument_VisitsOneArgument(IgnoreOptions options) { using var d = "{ foo{ names(size: 10) } }".Parse(new ParserOptions { Ignore = options }); @@ -306,8 +325,9 @@ public void Visit_OneDefinitionWithOneNestedArgument_VisitsOneArgument(IgnoreOpt [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_StringValueArgument_VisitsOneStringValue(IgnoreOptions options) { using var d = "{ stuff(id : \"abc\") }".Parse(new ParserOptions { Ignore = options }); @@ -318,8 +338,9 @@ public void Visit_StringValueArgument_VisitsOneStringValue(IgnoreOptions options [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_TwoDefinitions_CallsVisitDefinitionTwice(IgnoreOptions options) { using var d = "{ a }\n{ b }".Parse(new ParserOptions { Ignore = options }); @@ -330,8 +351,9 @@ public void Visit_TwoDefinitions_CallsVisitDefinitionTwice(IgnoreOptions options [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_TwoFieldSelections_VisitsFieldSelectionTwice(IgnoreOptions options) { using var d = "{ a, b }".Parse(new ParserOptions { Ignore = options }); @@ -342,8 +364,9 @@ public void Visit_TwoFieldSelections_VisitsFieldSelectionTwice(IgnoreOptions opt [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_TwoFieldSelections_VisitsTwoFieldNames(IgnoreOptions options) { using var d = "{ a, b }".Parse(new ParserOptions { Ignore = options }); @@ -354,8 +377,9 @@ public void Visit_TwoFieldSelections_VisitsTwoFieldNames(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_TwoFieldSelections_VisitsTwoFieldNamesAndDefinitionName(IgnoreOptions options) { using var d = "query foo { a, b }".Parse(new ParserOptions { Ignore = options }); @@ -366,8 +390,9 @@ public void Visit_TwoFieldSelections_VisitsTwoFieldNamesAndDefinitionName(Ignore [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_TwoFieldSelectionsWithOneNested_VisitsFiveFieldSelections(IgnoreOptions options) { using var d = "{a, nested { x, y }, b}".Parse(new ParserOptions { Ignore = options }); @@ -378,8 +403,9 @@ public void Visit_TwoFieldSelectionsWithOneNested_VisitsFiveFieldSelections(Igno [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Visit_TwoFieldSelectionsWithOneNested_VisitsFiveNames(IgnoreOptions options) { using var d = "{a, nested { x, y }, b}".Parse(new ParserOptions { Ignore = options }); diff --git a/src/GraphQLParser.Tests/Issue2478_GraphQL_NET.cs b/src/GraphQLParser.Tests/Issue2478_GraphQL_NET.cs index 8128e4fc..e154d29b 100644 --- a/src/GraphQLParser.Tests/Issue2478_GraphQL_NET.cs +++ b/src/GraphQLParser.Tests/Issue2478_GraphQL_NET.cs @@ -9,8 +9,9 @@ public class Issue2478_GraphQL_NET { [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void TestSchemaWithTwoInterfaceImplemented(IgnoreOptions options) { string query = @" diff --git a/src/GraphQLParser.Tests/Issue82.cs b/src/GraphQLParser.Tests/Issue82.cs index 79f93380..c1c34faf 100644 --- a/src/GraphQLParser.Tests/Issue82.cs +++ b/src/GraphQLParser.Tests/Issue82.cs @@ -15,8 +15,9 @@ public class Issue82 [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_Named_And_Literal_Variables(IgnoreOptions options) { using var document = _query.Parse(new ParserOptions { Ignore = options }); diff --git a/src/GraphQLParser.Tests/ParserTests.cs b/src/GraphQLParser.Tests/ParserTests.cs index 5ca01510..b35a9b41 100644 --- a/src/GraphQLParser.Tests/ParserTests.cs +++ b/src/GraphQLParser.Tests/ParserTests.cs @@ -47,8 +47,9 @@ public void Extra_Comments_Should_Read_Correctly(IgnoreOptions options) [Theory] //[InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + //[InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Comments_Can_Be_Ignored(IgnoreOptions options) { const string query = @" @@ -188,8 +189,9 @@ scalar JSON [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_Unicode_Char_At_EOF_Should_Throw(IgnoreOptions options) { Should.Throw(() => "{\"\\ue }".Parse(new ParserOptions { Ignore = options })); @@ -197,8 +199,9 @@ public void Parse_Unicode_Char_At_EOF_Should_Throw(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + //[InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] public void Parse_FieldInput_HasCorrectLocations(IgnoreOptions options) { // { field } @@ -212,8 +215,9 @@ public void Parse_FieldInput_HasCorrectLocations(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldInput_HasOneOperationDefinition(IgnoreOptions options) { using var document = ParseGraphQLFieldSource(options); @@ -223,8 +227,9 @@ public void Parse_FieldInput_HasOneOperationDefinition(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldInput_NameIsNull(IgnoreOptions options) { using var document = ParseGraphQLFieldSource(options); @@ -234,8 +239,9 @@ public void Parse_FieldInput_NameIsNull(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldInput_OperationIsQuery(IgnoreOptions options) { using var document = ParseGraphQLFieldSource(options); @@ -245,8 +251,9 @@ public void Parse_FieldInput_OperationIsQuery(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldInput_ReturnsDocumentNode(IgnoreOptions options) { using var document = ParseGraphQLFieldSource(options); @@ -256,8 +263,9 @@ public void Parse_FieldInput_ReturnsDocumentNode(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldInput_SelectionSetContainsSingleFieldSelection(IgnoreOptions options) { using var document = ParseGraphQLFieldSource(options); @@ -267,8 +275,9 @@ public void Parse_FieldInput_SelectionSetContainsSingleFieldSelection(IgnoreOpti [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + //[InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] public void Parse_FieldWithOperationTypeAndNameInput_HasCorrectLocations(IgnoreOptions options) { // mutation Foo { field } @@ -283,8 +292,9 @@ public void Parse_FieldWithOperationTypeAndNameInput_HasCorrectLocations(IgnoreO [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldWithOperationTypeAndNameInput_HasOneOperationDefinition(IgnoreOptions options) { using var document = ParseGraphQLFieldWithOperationTypeAndNameSource(options); @@ -294,8 +304,9 @@ public void Parse_FieldWithOperationTypeAndNameInput_HasOneOperationDefinition(I [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldWithOperationTypeAndNameInput_NameIsNull(IgnoreOptions options) { using var document = ParseGraphQLFieldWithOperationTypeAndNameSource(options); @@ -305,8 +316,9 @@ public void Parse_FieldWithOperationTypeAndNameInput_NameIsNull(IgnoreOptions op [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldWithOperationTypeAndNameInput_OperationIsQuery(IgnoreOptions options) { using var document = ParseGraphQLFieldWithOperationTypeAndNameSource(options); @@ -316,8 +328,9 @@ public void Parse_FieldWithOperationTypeAndNameInput_OperationIsQuery(IgnoreOpti [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldWithOperationTypeAndNameInput_ReturnsDocumentNode(IgnoreOptions options) { using var document = ParseGraphQLFieldWithOperationTypeAndNameSource(options); @@ -327,8 +340,9 @@ public void Parse_FieldWithOperationTypeAndNameInput_ReturnsDocumentNode(IgnoreO [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FieldWithOperationTypeAndNameInput_SelectionSetContainsSingleFieldWithOperationTypeAndNameSelection(IgnoreOptions options) { using var document = ParseGraphQLFieldWithOperationTypeAndNameSource(options); @@ -356,8 +370,9 @@ public void Parse_KitchenSink_DoesNotThrowError(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_NullInput_EmptyDocument(IgnoreOptions options) { using var document = ((string)null).Parse(new ParserOptions { Ignore = options }); @@ -367,8 +382,9 @@ public void Parse_NullInput_EmptyDocument(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_VariableInlineValues_DoesNotThrowError(IgnoreOptions options) { using ("{ field(complex: { a: { b: [ $var ] } }) }".Parse(new ParserOptions { Ignore = options })) @@ -378,8 +394,9 @@ public void Parse_VariableInlineValues_DoesNotThrowError(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_Empty_Field_Arguments_Should_Throw(IgnoreOptions options) { Should.Throw(() => "{ a() }".Parse(new ParserOptions { Ignore = options })); @@ -387,8 +404,9 @@ public void Parse_Empty_Field_Arguments_Should_Throw(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_Empty_Directive_Arguments_Should_Throw(IgnoreOptions options) { Should.Throw(() => "directive @dir() on FIELD_DEFINITION".Parse(new ParserOptions { Ignore = options })); @@ -396,8 +414,9 @@ public void Parse_Empty_Directive_Arguments_Should_Throw(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_Empty_Enum_Values_Should_Throw(IgnoreOptions options) { Should.Throw(() => "enum Empty { }".Parse(new ParserOptions { Ignore = options })); @@ -405,8 +424,9 @@ public void Parse_Empty_Enum_Values_Should_Throw(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_Empty_SelectionSet_Should_Throw(IgnoreOptions options) { Should.Throw(() => "{ a { } }".Parse(new ParserOptions { Ignore = options })); @@ -414,8 +434,9 @@ public void Parse_Empty_SelectionSet_Should_Throw(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_Empty_VariableDefinitions_Should_Throw(IgnoreOptions options) { Should.Throw(() => "query test() { a }".Parse(new ParserOptions { Ignore = options })); @@ -522,11 +543,17 @@ public void Should_Throw_On_Empty_Types_With_Braces(string text, int line, int c [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Descriptions_Should_Read_Correctly(IgnoreOptions options) { using var document = @" +""Super schema"" +schema { + query: String +} + ""A JSON scalar"" scalar JSON @@ -582,7 +609,10 @@ directive @TestDirective ( ) on QUERY ".Parse(new ParserOptions { Ignore = options }); var defs = document.Definitions; - defs.Count.ShouldBe(7); + defs.Count.ShouldBe(8); + + var schemaDef = defs.Single(x => x is GraphQLSchemaDefinition) as GraphQLSchemaDefinition; + schemaDef.Description.Value.ShouldBe("Super schema"); var scalarDef = defs.Single(x => x is GraphQLScalarTypeDefinition) as GraphQLScalarTypeDefinition; scalarDef.Name.Value.ShouldBe("JSON"); @@ -646,11 +676,19 @@ directive @TestDirective ( [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Descriptions_WithComments_Should_Read_Correctly_1(IgnoreOptions options) { using var document = @" +# comment -1 +""Super schema"" +# comment 0 +schema { + query: String +} + # comment 1 ""A JSON scalar"" # comment 2 @@ -738,9 +776,14 @@ directive @TestDirective ( ) on QUERY ".Parse(new ParserOptions { Ignore = options }); var defs = document.Definitions; - defs.Count.ShouldBe(7); + defs.Count.ShouldBe(8); var parseComments = options == IgnoreOptions.None; + var schemaDef = defs.Single(x => x is GraphQLSchemaDefinition) as GraphQLSchemaDefinition; + schemaDef.Description.Value.ShouldBe("Super schema"); + if (parseComments) + schemaDef.Comment.Text.ShouldBe(" comment 0"); + var scalarDef = defs.Single(x => x is GraphQLScalarTypeDefinition) as GraphQLScalarTypeDefinition; scalarDef.Name.Value.ShouldBe("JSON"); scalarDef.Description.Value.ShouldBe("A JSON scalar"); @@ -833,11 +876,18 @@ directive @TestDirective ( [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Descriptions_WithComments_Should_Read_Correctly_2(IgnoreOptions options) { using var document = @" +""Super schema"" +# comment 1 +schema { + query: String +} + ""A JSON scalar"" # comment 2 scalar JSON @@ -910,9 +960,14 @@ directive @TestDirective ( ) on QUERY ".Parse(new ParserOptions { Ignore = options }); var defs = document.Definitions; - defs.Count.ShouldBe(7); + defs.Count.ShouldBe(8); var parseComments = options == IgnoreOptions.None; + var schemaDef = defs.Single(x => x is GraphQLSchemaDefinition) as GraphQLSchemaDefinition; + schemaDef.Description.Value.ShouldBe("Super schema"); + if (parseComments) + schemaDef.Comment.Text.ShouldBe(" comment 1"); + var scalarDef = defs.Single(x => x is GraphQLScalarTypeDefinition) as GraphQLScalarTypeDefinition; scalarDef.Name.Value.ShouldBe("JSON"); scalarDef.Description.Value.ShouldBe("A JSON scalar"); @@ -1005,11 +1060,18 @@ directive @TestDirective ( [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Descriptions_WithComments_Should_Read_Correctly_3(IgnoreOptions options) { using var document = @" +# comment 0 +""Super schema"" +schema { + query: String +} + # comment 1 ""A JSON scalar"" scalar JSON @@ -1082,9 +1144,14 @@ directive @TestDirective ( ) on QUERY ".Parse(new ParserOptions { Ignore = options }); var defs = document.Definitions; - defs.Count.ShouldBe(7); + defs.Count.ShouldBe(8); var parseComments = options == IgnoreOptions.None; + var schemaDef = defs.Single(x => x is GraphQLSchemaDefinition) as GraphQLSchemaDefinition; + schemaDef.Description.Value.ShouldBe("Super schema"); + if (parseComments) + schemaDef.Comment.Text.ShouldBe(" comment 0"); + var scalarDef = defs.Single(x => x is GraphQLScalarTypeDefinition) as GraphQLScalarTypeDefinition; scalarDef.Name.Value.ShouldBe("JSON"); scalarDef.Description.Value.ShouldBe("A JSON scalar"); diff --git a/src/GraphQLParser.Tests/Validation/ParserValidationTests.cs b/src/GraphQLParser.Tests/Validation/ParserValidationTests.cs index ec1f689e..818b635e 100644 --- a/src/GraphQLParser.Tests/Validation/ParserValidationTests.cs +++ b/src/GraphQLParser.Tests/Validation/ParserValidationTests.cs @@ -8,8 +8,9 @@ public class ParserValidationTests { [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_FragmentInvalidOnName_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "fragment on on on { on }".Parse(new ParserOptions { Ignore = options })); @@ -25,8 +26,9 @@ public void Parse_FragmentInvalidOnName_ThrowsExceptionWithCorrectMessage(Ignore [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_InvalidDefaultValue_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "query Foo($x: Complex = { a: { b: [ $var ] } }) { field }".Parse(new ParserOptions { Ignore = options })); @@ -42,8 +44,9 @@ public void Parse_InvalidDefaultValue_ThrowsExceptionWithCorrectMessage(IgnoreOp [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_InvalidFragmentNameInSpread_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "{ ...on }".Parse(new ParserOptions { Ignore = options })); @@ -59,8 +62,9 @@ public void Parse_InvalidFragmentNameInSpread_ThrowsExceptionWithCorrectMessage( [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_LonelySpread_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "...".Parse(new ParserOptions { Ignore = options })); @@ -76,8 +80,9 @@ public void Parse_LonelySpread_ThrowsExceptionWithCorrectMessage(IgnoreOptions o [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_MissingEndingBrace_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "{".Parse(new ParserOptions { Ignore = options })); @@ -93,8 +98,9 @@ public void Parse_MissingEndingBrace_ThrowsExceptionWithCorrectMessage(IgnoreOpt [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_MissingFieldNameWhenAliasing_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "{ field: {} }".Parse(new ParserOptions { Ignore = options })); @@ -110,8 +116,9 @@ public void Parse_MissingFieldNameWhenAliasing_ThrowsExceptionWithCorrectMessage [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_MissingFragmentType_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "{ ...MissingOn }\nfragment MissingOn Type".Parse(new ParserOptions { Ignore = options })); @@ -128,8 +135,9 @@ public void Parse_MissingFragmentType_ThrowsExceptionWithCorrectMessage(IgnoreOp [Theory] [InlineData(IgnoreOptions.None)] - [InlineData(IgnoreOptions.IgnoreComments)] - [InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_UnknownOperation_ThrowsExceptionWithCorrectMessage(IgnoreOptions options) { var exception = Should.Throw(() => "notanoperation Foo { field }".Parse(new ParserOptions { Ignore = options })); diff --git a/src/GraphQLParser/AST/ASTNodeKind.cs b/src/GraphQLParser/AST/ASTNodeKind.cs index 9d749cbc..8995a02d 100644 --- a/src/GraphQLParser/AST/ASTNodeKind.cs +++ b/src/GraphQLParser/AST/ASTNodeKind.cs @@ -91,7 +91,7 @@ public enum ASTNodeKind Comment, /// - /// Description of a type definition. + /// Description of a GraphQL definition. /// Description, } diff --git a/src/GraphQLParser/AST/GraphQLComment.cs b/src/GraphQLParser/AST/GraphQLComment.cs index 08755534..6a08592f 100644 --- a/src/GraphQLParser/AST/GraphQLComment.cs +++ b/src/GraphQLParser/AST/GraphQLComment.cs @@ -6,7 +6,6 @@ namespace GraphQLParser.AST [DebuggerDisplay("{Text}")] public class GraphQLComment : ASTNode { - private GraphQLLocation _location; //private GraphQLComment? _comment; /// @@ -17,12 +16,6 @@ public class GraphQLComment : ASTNode /// public ROM Text { get; set; } - public override GraphQLLocation Location - { - get => _location; - set => _location = value; - } - // Comment itself can't have a comment //public override GraphQLComment? Comment //{ @@ -30,4 +23,15 @@ public override GraphQLLocation Location // set => _comment = value; //} } + + internal class GraphQLCommentFull : GraphQLComment + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } } diff --git a/src/GraphQLParser/AST/GraphQLDescription.cs b/src/GraphQLParser/AST/GraphQLDescription.cs index f939c8b5..35d18761 100644 --- a/src/GraphQLParser/AST/GraphQLDescription.cs +++ b/src/GraphQLParser/AST/GraphQLDescription.cs @@ -1,5 +1,9 @@ +using System.Diagnostics; + namespace GraphQLParser.AST { + /// + [DebuggerDisplay("{Value}")] public class GraphQLDescription : ASTNode { public override ASTNodeKind Kind => ASTNodeKind.Description; diff --git a/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs b/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs index 6a5cb5dd..4db3e61a 100644 --- a/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs @@ -5,7 +5,7 @@ namespace GraphQLParser.AST /// /// Represents a directive definition. /// - public class GraphQLDirectiveDefinition : GraphQLTypeDefinitionWithDescription + public class GraphQLDirectiveDefinition : GraphQLTypeDefinition { public List? Arguments { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs index c5959c40..9fd18ad3 100644 --- a/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLEnumTypeDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLEnumTypeDefinition : GraphQLTypeDefinition, IHasDirectivesNode { /// public List? Directives { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs b/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs index 47dd2b69..3dc28fb2 100644 --- a/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLEnumValueDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLEnumValueDefinition : GraphQLTypeDefinition, IHasDirectivesNode { /// public List? Directives { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLFieldDefinition.cs b/src/GraphQLParser/AST/GraphQLFieldDefinition.cs index c9efd69a..003041c9 100644 --- a/src/GraphQLParser/AST/GraphQLFieldDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLFieldDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLFieldDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLFieldDefinition : GraphQLTypeDefinition, IHasDirectivesNode { public List? Arguments { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs index 7645e7ab..02f7af8f 100644 --- a/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLInputObjectTypeDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLInputObjectTypeDefinition : GraphQLTypeDefinition, IHasDirectivesNode { /// public List? Directives { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs b/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs index 18d82f1e..f5388c71 100644 --- a/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLInputValueDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLInputValueDefinition : GraphQLTypeDefinition, IHasDirectivesNode { public GraphQLValue? DefaultValue { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs index d75e11ef..7d78bfdd 100644 --- a/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLInterfaceTypeDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLInterfaceTypeDefinition : GraphQLTypeDefinition, IHasDirectivesNode { /// public List? Directives { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs index 83142093..708cd948 100644 --- a/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLObjectTypeDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLObjectTypeDefinition : GraphQLTypeDefinition, IHasDirectivesNode { /// public List? Directives { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs index c4e71ab4..00d91e98 100644 --- a/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLScalarTypeDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLScalarTypeDefinition : GraphQLTypeDefinition, IHasDirectivesNode { /// public List? Directives { get; set; } diff --git a/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs b/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs index 5679ec59..4096930d 100644 --- a/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs @@ -2,11 +2,14 @@ namespace GraphQLParser.AST { - public class GraphQLSchemaDefinition : ASTNode, IHasDirectivesNode + public class GraphQLSchemaDefinition : ASTNode, IHasDirectivesNode, IHasDescriptionNode { /// public List? Directives { get; set; } + /// + public GraphQLDescription? Description { get; set; } + /// public override ASTNodeKind Kind => ASTNodeKind.SchemaDefinition; diff --git a/src/GraphQLParser/AST/GraphQLTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLTypeDefinition.cs index 391908b7..2f81b7a7 100644 --- a/src/GraphQLParser/AST/GraphQLTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLTypeDefinition.cs @@ -1,16 +1,11 @@ namespace GraphQLParser.AST { - public abstract class GraphQLTypeDefinition : ASTNode, INamedNode + public abstract class GraphQLTypeDefinition : ASTNode, INamedNode, IHasDescriptionNode { /// public GraphQLName? Name { get; set; } - } - public abstract class GraphQLTypeDefinitionWithDescription : GraphQLTypeDefinition, IHasDescription - { - /// - /// Description of the node - /// + /// public GraphQLDescription? Description { get; set; } } } diff --git a/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs index 6409eb8a..3ee86ab5 100644 --- a/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLUnionTypeDefinition : GraphQLTypeDefinitionWithDescription, IHasDirectivesNode + public class GraphQLUnionTypeDefinition : GraphQLTypeDefinition, IHasDirectivesNode { /// public List? Directives { get; set; } diff --git a/src/GraphQLParser/AST/IHasDescription.cs b/src/GraphQLParser/AST/IHasDescription.cs deleted file mode 100644 index 9a2a1b2b..00000000 --- a/src/GraphQLParser/AST/IHasDescription.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace GraphQLParser.AST -{ - public interface IHasDescription - { - GraphQLDescription? Description { get; set; } - } -} diff --git a/src/GraphQLParser/AST/IHasDescriptionNode.cs b/src/GraphQLParser/AST/IHasDescriptionNode.cs new file mode 100644 index 00000000..b6c7d10c --- /dev/null +++ b/src/GraphQLParser/AST/IHasDescriptionNode.cs @@ -0,0 +1,14 @@ +namespace GraphQLParser.AST +{ + /// + /// Represents an AST node that may have description applied to it. + /// As a rule, these are definition nodes: type, arguments, enum values etc. + /// + public interface IHasDescriptionNode + { + /// + /// Description of a GraphQL definition. + /// + GraphQLDescription? Description { get; set; } + } +} diff --git a/src/GraphQLParser/IgnoreOptions.cs b/src/GraphQLParser/IgnoreOptions.cs index 5e03e7a9..ea035167 100644 --- a/src/GraphQLParser/IgnoreOptions.cs +++ b/src/GraphQLParser/IgnoreOptions.cs @@ -1,23 +1,31 @@ +using System; + namespace GraphQLParser { /// /// Options to selectively ignore some information when parsing GraphQL document. /// + [Flags] public enum IgnoreOptions { + /// + /// No information is ignored. + /// + None = 0, + /// /// Specifies whether to ignore comments when parsing GraphQL document. /// - IgnoreComments = 0, + Comments = 1, /// - /// Specifies whether to ignore comments and token locations when parsing GraphQL document. + /// Specifies whether to ignore token locations when parsing GraphQL document. /// - IgnoreCommentsAndLocations = 1, + Locations = 2, /// - /// No information is ignored. + /// Specifies whether to ignore comments and token locations when parsing GraphQL document. /// - None = 2 + All = Comments | Locations, } } diff --git a/src/GraphQLParser/ParserContext.Parse.cs b/src/GraphQLParser/ParserContext.Parse.cs index 926fd391..62481fa1 100644 --- a/src/GraphQLParser/ParserContext.Parse.cs +++ b/src/GraphQLParser/ParserContext.Parse.cs @@ -33,7 +33,7 @@ private GraphQLArgument ParseArgument() var comment = GetComment(); int start = _currentToken.Start; - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLArgument { Name = ParseName(), @@ -86,7 +86,7 @@ private GraphQLArgument ParseArgument() private GraphQLValue ParseBooleanValue(Token token) { Advance(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLScalarValue(ASTNodeKind.BooleanValue) { Value = token.Value, @@ -147,7 +147,8 @@ private List ParseDefinitionsIfNotEOF() private GraphQLComment? ParseComment() { - if (_ignoreOptions != IgnoreOptions.None) + // skip comments + if (_ignoreOptions.HasFlag(IgnoreOptions.Comments)) { while (Peek(TokenKind.COMMENT)) { @@ -173,14 +174,12 @@ private List ParseDefinitionsIfNotEOF() } while (_currentToken.Kind == TokenKind.COMMENT); - var comment = new GraphQLComment - { - Location = new GraphQLLocation - ( - start, - end - ) - }; + var comment = _ignoreOptions.HasFlag(IgnoreOptions.Locations) + ? new GraphQLComment() + : new GraphQLCommentFull + { + Location = new GraphQLLocation(start, end), + }; if (text.Count == 1) { @@ -210,7 +209,7 @@ private GraphQLDirective ParseDirective() { int start = _currentToken.Start; Expect(TokenKind.AT); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLDirective { Name = ParseName(), @@ -250,7 +249,7 @@ private GraphQLDirectiveDefinition ParseDirectiveDefinition() ExpectKeyword("on"); var locations = ParseDirectiveLocations(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLDirectiveDefinition { Name = name, @@ -323,14 +322,14 @@ private List ParseDirectiveLocations() private GraphQLDocument ParseDocument() { - _document = _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations ? new GraphQLDocument() : new GraphQLDocumentFull(); + _document = _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLDocument() : new GraphQLDocumentFull(); int start = _currentToken.Start; var definitions = ParseDefinitionsIfNotEOF(); SetCurrentComment(null); - if (_ignoreOptions != IgnoreOptions.IgnoreCommentsAndLocations) + if (!_ignoreOptions.HasFlag(IgnoreOptions.Locations)) { _document.Location = new GraphQLLocation ( @@ -358,7 +357,7 @@ private GraphQLEnumTypeDefinition ParseEnumTypeDefinition() var comment = GetComment(); ExpectKeyword("enum"); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLEnumTypeDefinition { Name = ParseName(), @@ -380,7 +379,7 @@ private GraphQLEnumTypeDefinition ParseEnumTypeDefinition() private GraphQLValue ParseEnumValue(Token token) { Advance(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLScalarValue(ASTNodeKind.EnumValue) { Value = token.Value, @@ -403,7 +402,7 @@ private GraphQLEnumValueDefinition ParseEnumValueDefinition() } var comment = GetComment(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLEnumValueDefinition { Name = ParseName(), @@ -435,7 +434,7 @@ private GraphQLFieldDefinition ParseFieldDefinition() var args = ParseArgumentDefs(); Expect(TokenKind.COLON); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLFieldDefinition { Name = name, @@ -475,7 +474,7 @@ private GraphQLFieldSelection ParseFieldSelection() name = nameOrAlias; } - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLFieldSelection { Alias = alias, @@ -500,7 +499,7 @@ private GraphQLValue ParseFloat(/*bool isConstant*/) { var token = _currentToken; Advance(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLScalarValue(ASTNodeKind.FloatValue) { Value = token.Value, @@ -525,7 +524,7 @@ private ASTNode ParseFragment() private ASTNode CreateGraphQLFragmentSpread(int start, GraphQLComment? comment) { - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLFragmentSpread { Name = ParseFragmentName(), @@ -542,7 +541,7 @@ private ASTNode CreateGraphQLFragmentSpread(int start, GraphQLComment? comment) private ASTNode CreateInlineFragment(int start, GraphQLComment? comment) { - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLInlineFragment { TypeCondition = ParseTypeCondition(), @@ -565,7 +564,7 @@ private GraphQLFragmentDefinition ParseFragmentDefinition() int start = _currentToken.Start; ExpectKeyword("fragment"); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLFragmentDefinition { Name = ParseFragmentName(), @@ -633,7 +632,7 @@ private GraphQLInputObjectTypeDefinition ParseInputObjectTypeDefinition() var comment = GetComment(); ExpectKeyword("input"); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLInputObjectTypeDefinition { Name = ParseName(), @@ -665,7 +664,7 @@ private GraphQLInputValueDefinition ParseInputValueDef() var name = ParseName(); Expect(TokenKind.COLON); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLInputValueDefinition { Name = name, @@ -691,7 +690,7 @@ private GraphQLValue ParseInt(/*bool isConstant*/) var token = _currentToken; Advance(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLScalarValue(ASTNodeKind.IntValue) { Value = token.Value, @@ -715,7 +714,7 @@ private GraphQLInterfaceTypeDefinition ParseInterfaceTypeDefinition() var comment = GetComment(); ExpectKeyword("interface"); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLInterfaceTypeDefinition { Name = ParseName(), @@ -741,7 +740,7 @@ private GraphQLValue ParseList(bool isConstant) ParseCallback constant = (ref ParserContext context) => context.ParseValueLiteral(true); ParseCallback value = (ref ParserContext context) => context.ParseValueLiteral(false); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLListValue(ASTNodeKind.ListValue) { Values = ZeroOrMore(TokenKind.BRACKET_L, isConstant ? constant : value, TokenKind.BRACKET_R), @@ -762,7 +761,7 @@ private GraphQLName ParseName() Expect(TokenKind.NAME); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLName { Value = value @@ -822,20 +821,23 @@ private GraphQLName ParseName() private ASTNode? ParseNamedDefinitionWithDescription() { - //look-ahead to next token + // look-ahead to next token (_currentToken remains unchanged) var token = Lexer.Lex(_source, _currentToken.End); - //skip comments + // skip comments while (token.Kind != TokenKind.EOF && token.Kind == TokenKind.COMMENT) { token = Lexer.Lex(_source, token.End); } - //verify this is a NAME + // verify this is a NAME if (token.Kind != TokenKind.NAME) return null; - //retrieve the value + // retrieve the value var value = token.Value; + if (value == "schema") + return ParseSchemaDefinition(); + if (value == "scalar") return ParseScalarTypeDefinition(); @@ -863,7 +865,7 @@ private GraphQLName ParseName() private GraphQLNamedType ParseNamedType() { int start = _currentToken.Start; - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLNamedType { Name = ParseName(), @@ -903,7 +905,7 @@ private GraphQLValue ParseObject(bool isConstant) var comment = GetComment(); int start = _currentToken.Start; - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLObjectValue { Fields = ParseObjectFields(isConstant), @@ -919,7 +921,7 @@ private GraphQLValue ParseObject(bool isConstant) private GraphQLValue ParseNullValue(Token token) { Advance(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLScalarValue(ASTNodeKind.NullValue) { Value = token.Value, @@ -935,7 +937,7 @@ private GraphQLObjectField ParseObjectField(bool isConstant) { var comment = GetComment(); int start = _currentToken.Start; - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLObjectField { Name = ParseName(), @@ -974,7 +976,7 @@ private GraphQLObjectTypeDefinition ParseObjectTypeDefinition() ExpectKeyword("type"); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLObjectTypeDefinition { Name = ParseName(), @@ -1007,7 +1009,7 @@ private ASTNode ParseOperationDefinition() private ASTNode CreateOperationDefinition(int start) { var comment = GetComment(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLOperationDefinition { Operation = OperationType.Query, @@ -1025,7 +1027,7 @@ private ASTNode CreateOperationDefinition(int start) private ASTNode CreateOperationDefinition(int start, OperationType operation, GraphQLName? name) { var comment = GetComment(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLOperationDefinition { Operation = operation, @@ -1067,7 +1069,7 @@ private GraphQLOperationTypeDefinition ParseOperationTypeDefinition() Expect(TokenKind.COLON); var type = ParseNamedType(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLOperationTypeDefinition { Operation = operation, @@ -1095,7 +1097,7 @@ private GraphQLScalarTypeDefinition ParseScalarTypeDefinition() var name = ParseName(); var directives = ParseDirectives(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLScalarTypeDefinition { Name = name, @@ -1114,23 +1116,31 @@ private GraphQLScalarTypeDefinition ParseScalarTypeDefinition() private GraphQLSchemaDefinition ParseSchemaDefinition() { - var comment = GetComment(); int start = _currentToken.Start; + GraphQLDescription? description = null; + if (Peek(TokenKind.STRING)) + { + description = ParseDescription(); + ParseComment(); + } + var comment = GetComment(); ExpectKeyword("schema"); var directives = ParseDirectives(); var operationTypes = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseOperationTypeDefinition(), TokenKind.BRACE_R); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLSchemaDefinition { Directives = directives, OperationTypes = operationTypes, + Description = description, } : new GraphQLSchemaDefinitionFull { Comment = comment, Directives = directives, OperationTypes = operationTypes, + Description = description, Location = GetLocation(start) }; } @@ -1145,7 +1155,7 @@ private ASTNode ParseSelection() private GraphQLSelectionSet ParseSelectionSet() { int start = _currentToken.Start; - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLSelectionSet { Selections = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseSelection(), TokenKind.BRACE_R), @@ -1161,7 +1171,7 @@ private GraphQLScalarValue ParseString(/*bool isConstant*/) { var token = _currentToken; Advance(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLScalarValue(ASTNodeKind.StringValue) { Value = token.Value, @@ -1177,7 +1187,7 @@ private GraphQLDescription ParseDescription() { var token = _currentToken; Advance(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLDescription() { Value = token.Value, @@ -1197,7 +1207,7 @@ private GraphQLType ParseType() { type = ParseType(); Expect(TokenKind.BRACKET_R); - type = _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + type = _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLListType { Type = type, @@ -1214,7 +1224,7 @@ private GraphQLType ParseType() } return Skip(TokenKind.BANG) - ? (_ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + ? (_ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLNonNullType { Type = type, @@ -1234,7 +1244,8 @@ private GraphQLTypeExtensionDefinition ParseTypeExtensionDefinition() ExpectKeyword("extend"); var definition = ParseObjectTypeDefinition(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + // Note that due to the spec extension definitions have no descriptions. + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLTypeExtensionDefinition { Name = definition.Name, @@ -1282,7 +1293,7 @@ private GraphQLUnionTypeDefinition ParseUnionTypeDefinition() Expect(TokenKind.EQUALS); var types = ParseUnionMembers(); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLUnionTypeDefinition { Name = name, @@ -1323,7 +1334,7 @@ private GraphQLVariable ParseVariable() int start = _currentToken.Start; Expect(TokenKind.DOLLAR); - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLVariable { Name = ParseName(), @@ -1340,7 +1351,7 @@ private GraphQLVariableDefinition ParseVariableDefinition() var comment = GetComment(); int start = _currentToken.Start; - return _ignoreOptions == IgnoreOptions.IgnoreCommentsAndLocations + return _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLVariableDefinition { Variable = ParseVariable(), From 2677be3ca98ece1c9c57cb3fa601195ee4365ea2 Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Sun, 7 Nov 2021 23:15:09 +0300 Subject: [PATCH 2/4] rework for locations and comments --- .../Files/CommentsOnValues.graphql | 34 + .../GraphQLAstVisitorTests.cs | 2 + src/GraphQLParser.Tests/ParserTests.cs | 110 ++- src/GraphQLParser/AST/GraphQLArgument.cs | 22 + src/GraphQLParser/AST/GraphQLComment.cs | 2 +- src/GraphQLParser/AST/GraphQLDescription.cs | 11 + src/GraphQLParser/AST/GraphQLDirective.cs | 35 +- .../AST/GraphQLDirectiveDefinition.cs | 22 + src/GraphQLParser/AST/GraphQLDocument.cs | 41 +- .../AST/GraphQLEnumTypeDefinition.cs | 22 + .../AST/GraphQLEnumValueDefinition.cs | 22 + .../AST/GraphQLFieldDefinition.cs | 22 + .../AST/GraphQLFieldSelection.cs | 22 + .../AST/GraphQLFragmentDefinition.cs | 21 + .../AST/GraphQLFragmentSpread.cs | 22 + .../AST/GraphQLInlineFragment.cs | 22 + .../AST/GraphQLInputObjectTypeDefinition.cs | 22 + .../AST/GraphQLInputValueDefinition.cs | 22 + .../AST/GraphQLInterfaceTypeDefinition.cs | 22 + src/GraphQLParser/AST/GraphQLListType.cs | 35 +- src/GraphQLParser/AST/GraphQLListValue.cs | 45 +- src/GraphQLParser/AST/GraphQLName.cs | 35 +- src/GraphQLParser/AST/GraphQLNamedType.cs | 35 +- src/GraphQLParser/AST/GraphQLNonNullType.cs | 35 +- src/GraphQLParser/AST/GraphQLObjectField.cs | 22 + .../AST/GraphQLObjectTypeDefinition.cs | 22 + src/GraphQLParser/AST/GraphQLObjectValue.cs | 22 + .../AST/GraphQLOperationDefinition.cs | 22 + .../AST/GraphQLOperationTypeDefinition.cs | 35 +- .../AST/GraphQLScalarTypeDefinition.cs | 22 + src/GraphQLParser/AST/GraphQLScalarValue.cs | 45 +- .../AST/GraphQLSchemaDefinition.cs | 22 + src/GraphQLParser/AST/GraphQLSelectionSet.cs | 35 +- .../AST/GraphQLTypeExtensionDefinition.cs | 22 + .../AST/GraphQLUnionTypeDefinition.cs | 22 + src/GraphQLParser/AST/GraphQLVariable.cs | 35 +- .../AST/GraphQLVariableDefinition.cs | 21 + src/GraphQLParser/IgnoreOptions.cs | 2 +- src/GraphQLParser/NodeHelper.cs | 416 +++++++++ src/GraphQLParser/ParserContext.Parse.cs | 872 +++++++----------- 40 files changed, 1651 insertions(+), 669 deletions(-) create mode 100644 src/GraphQLParser.Tests/Files/CommentsOnValues.graphql create mode 100644 src/GraphQLParser/NodeHelper.cs diff --git a/src/GraphQLParser.Tests/Files/CommentsOnValues.graphql b/src/GraphQLParser.Tests/Files/CommentsOnValues.graphql new file mode 100644 index 00000000..32255f3d --- /dev/null +++ b/src/GraphQLParser.Tests/Files/CommentsOnValues.graphql @@ -0,0 +1,34 @@ +query q($id: ID) { + person( + valBool: + #comment for bool + true, + valNull: + #comment for null + null, + valEnum: + #comment for enum + RED, + valList: + #comment for list + [1,2,3], + valObj: + #comment for object + { a: 1 }, + valInt: + #comment for int + 7, + valFloat: + #comment for float + 1.4, + valString: + #comment for string + "!#$", + valVariable: + #comment for variable + $id + ) + { + a + } +} diff --git a/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs b/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs index 6bf56e2e..06fc971a 100644 --- a/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs +++ b/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs @@ -55,6 +55,7 @@ public GraphQLAstVisitorTests() [Theory] [InlineData(IgnoreOptions.None)] [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] public void Visit_BooleanValueArgument_VisitsOneBooleanValue(IgnoreOptions options) { @@ -67,6 +68,7 @@ public void Visit_BooleanValueArgument_VisitsOneBooleanValue(IgnoreOptions optio [Theory] [InlineData(IgnoreOptions.None)] [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] public void Visit_DefinitionWithSingleFragmentSpread_VisitsFragmentSpreadOneTime(IgnoreOptions options) { diff --git a/src/GraphQLParser.Tests/ParserTests.cs b/src/GraphQLParser.Tests/ParserTests.cs index b35a9b41..4ee1936f 100644 --- a/src/GraphQLParser.Tests/ParserTests.cs +++ b/src/GraphQLParser.Tests/ParserTests.cs @@ -14,8 +14,9 @@ public class ParserTests [Theory] [InlineData(IgnoreOptions.None)] - //[InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] public void Extra_Comments_Should_Read_Correctly(IgnoreOptions options) { string query = "ExtraComments".ReadGraphQLFile(); @@ -71,9 +72,10 @@ public void Comments_Can_Be_Ignored(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - //[InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] - public void Comments_on_FragmentSpread_Should_Read_Correclty(IgnoreOptions options) + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_FragmentSpread_Should_Read_Correctly(IgnoreOptions options) { string query = "CommentsOnFragmentSpread".ReadGraphQLFile(); @@ -89,9 +91,55 @@ public void Comments_on_FragmentSpread_Should_Read_Correclty(IgnoreOptions optio [Theory] [InlineData(IgnoreOptions.None)] - //[InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] - public void Comments_on_FragmentInline_Should_Read_Correclty(IgnoreOptions options) + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_Values_Should_Read_Correctly(IgnoreOptions options) + { + string query = "CommentsOnValues".ReadGraphQLFile(); + + using var document = query.Parse(new ParserOptions { Ignore = options }); + document.Definitions.Count.ShouldBe(1); + var def = document.Definitions.First() as GraphQLOperationDefinition; + def.SelectionSet.Selections.Count.ShouldBe(1); + var field = def.SelectionSet.Selections.First() as GraphQLFieldSelection; + field.SelectionSet.Selections.Count.ShouldBe(1); + field.Arguments.Count.ShouldBe(9); + + var boolValue = field.Arguments[0].Value.ShouldBeAssignableTo(); + boolValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for bool"); + + var nullValue = field.Arguments[1].Value.ShouldBeAssignableTo(); + nullValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for null"); + + var enumValue = field.Arguments[2].Value.ShouldBeAssignableTo(); + enumValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for enum"); + + var listValue = field.Arguments[3].Value.ShouldBeAssignableTo(); + listValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for list"); + + var objValue = field.Arguments[4].Value.ShouldBeAssignableTo(); + objValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for object"); + + var intValue = field.Arguments[5].Value.ShouldBeAssignableTo(); + intValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for int"); + + var floatValue = field.Arguments[6].Value.ShouldBeAssignableTo(); + floatValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for float"); + + var stringValue = field.Arguments[7].Value.ShouldBeAssignableTo(); + stringValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for string"); + + var varValue = field.Arguments[8].Value.ShouldBeAssignableTo(); + varValue.Comment.ShouldNotBeNull().Text.ShouldBe("comment for variable"); + } + + [Theory] + [InlineData(IgnoreOptions.None)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_FragmentInline_Should_Read_Correctly(IgnoreOptions options) { string query = "CommentsOnInlineFragment".ReadGraphQLFile(); @@ -107,9 +155,10 @@ public void Comments_on_FragmentInline_Should_Read_Correclty(IgnoreOptions optio [Theory] [InlineData(IgnoreOptions.None)] - //[InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] - public void Comments_on_Variable_Should_Read_Correclty(IgnoreOptions options) + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_Variable_Should_Read_Correctly(IgnoreOptions options) { string query = "CommentsOnVariables".ReadGraphQLFile(); @@ -124,8 +173,9 @@ public void Comments_on_Variable_Should_Read_Correclty(IgnoreOptions options) [Theory] [InlineData(IgnoreOptions.None)] - //[InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] public void Comments_On_SelectionSet_Should_Read_Correctly(IgnoreOptions options) { using var document = @" @@ -147,9 +197,10 @@ public void Comments_On_SelectionSet_Should_Read_Correctly(IgnoreOptions options [Theory] [InlineData(IgnoreOptions.None)] - //[InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] - public void Comments_On_Enums_Should_Read_Correctly(IgnoreOptions options) + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_On_Enum_Definitions_Should_Read_Correctly(IgnoreOptions options) { using var document = @" # different animals @@ -352,20 +403,31 @@ public void Parse_FieldWithOperationTypeAndNameInput_SelectionSetContainsSingleF [Theory] [InlineData(IgnoreOptions.None)] - //[InlineData(IgnoreOptions.IgnoreComments)] - //[InlineData(IgnoreOptions.IgnoreCommentsAndLocations)] + [InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + [InlineData(IgnoreOptions.All)] public void Parse_KitchenSink_DoesNotThrowError(IgnoreOptions options) { using var document = "KitchenSink".ReadGraphQLFile().Parse(new ParserOptions { Ignore = options }); var typeDef = document.Definitions.OfType().First(d => d.Name.Value == "Foo"); var fieldDef = typeDef.Fields.First(d => d.Name.Value == "three"); - fieldDef.Comment.ShouldNotBeNull().Text.ShouldBe($" multiline comments{_nl} with very importand description #{_nl} # and symbol # and ##"); + if (options.HasFlag(IgnoreOptions.Comments)) + fieldDef.Comment.ShouldBeNull(); + else + fieldDef.Comment.ShouldNotBeNull().Text.ShouldBe($" multiline comments{_nl} with very importand description #{_nl} # and symbol # and ##"); // Schema description // https://github.com/graphql/graphql-spec/pull/466 var comment = document.Definitions.OfType().First().Comment; - comment.ShouldNotBeNull(); - ((string)comment.Text).StartsWith(" Copyright (c) 2015, Facebook, Inc.").ShouldBeTrue(); + if (options.HasFlag(IgnoreOptions.Comments)) + { + comment.ShouldBeNull(); + } + else + { + comment.ShouldNotBeNull(); + ((string)comment.Text).StartsWith(" Copyright (c) 2015, Facebook, Inc.").ShouldBeTrue(); + } } [Theory] @@ -777,7 +839,7 @@ directive @TestDirective ( ".Parse(new ParserOptions { Ignore = options }); var defs = document.Definitions; defs.Count.ShouldBe(8); - var parseComments = options == IgnoreOptions.None; + var parseComments = !options.HasFlag(IgnoreOptions.Comments); var schemaDef = defs.Single(x => x is GraphQLSchemaDefinition) as GraphQLSchemaDefinition; schemaDef.Description.Value.ShouldBe("Super schema"); @@ -961,7 +1023,7 @@ directive @TestDirective ( ".Parse(new ParserOptions { Ignore = options }); var defs = document.Definitions; defs.Count.ShouldBe(8); - var parseComments = options == IgnoreOptions.None; + var parseComments = !options.HasFlag(IgnoreOptions.Comments); var schemaDef = defs.Single(x => x is GraphQLSchemaDefinition) as GraphQLSchemaDefinition; schemaDef.Description.Value.ShouldBe("Super schema"); @@ -1145,7 +1207,7 @@ directive @TestDirective ( ".Parse(new ParserOptions { Ignore = options }); var defs = document.Definitions; defs.Count.ShouldBe(8); - var parseComments = options == IgnoreOptions.None; + var parseComments = !options.HasFlag(IgnoreOptions.Comments); var schemaDef = defs.Single(x => x is GraphQLSchemaDefinition) as GraphQLSchemaDefinition; schemaDef.Description.Value.ShouldBe("Super schema"); diff --git a/src/GraphQLParser/AST/GraphQLArgument.cs b/src/GraphQLParser/AST/GraphQLArgument.cs index 5411b362..0a961f49 100644 --- a/src/GraphQLParser/AST/GraphQLArgument.cs +++ b/src/GraphQLParser/AST/GraphQLArgument.cs @@ -11,6 +11,28 @@ public class GraphQLArgument : ASTNode, INamedNode public GraphQLValue? Value { get; set; } } + internal sealed class GraphQLArgumentWithLocation : GraphQLArgument + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLArgumentWithComment : GraphQLArgument + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLArgumentFull : GraphQLArgument { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLComment.cs b/src/GraphQLParser/AST/GraphQLComment.cs index 6a08592f..942a1081 100644 --- a/src/GraphQLParser/AST/GraphQLComment.cs +++ b/src/GraphQLParser/AST/GraphQLComment.cs @@ -24,7 +24,7 @@ public class GraphQLComment : ASTNode //} } - internal class GraphQLCommentFull : GraphQLComment + internal class GraphQLCommentWithLocation : GraphQLComment { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLDescription.cs b/src/GraphQLParser/AST/GraphQLDescription.cs index 35d18761..0774e9f8 100644 --- a/src/GraphQLParser/AST/GraphQLDescription.cs +++ b/src/GraphQLParser/AST/GraphQLDescription.cs @@ -10,4 +10,15 @@ public class GraphQLDescription : ASTNode public ROM Value { get; set; } } + + internal sealed class GraphQLDescriptionWithLocation : GraphQLDescription + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } } diff --git a/src/GraphQLParser/AST/GraphQLDirective.cs b/src/GraphQLParser/AST/GraphQLDirective.cs index 9715a80a..a20d5279 100644 --- a/src/GraphQLParser/AST/GraphQLDirective.cs +++ b/src/GraphQLParser/AST/GraphQLDirective.cs @@ -16,10 +16,32 @@ public class GraphQLDirective : ASTNode, INamedNode public GraphQLName? Name { get; set; } } + internal sealed class GraphQLDirectiveWithLocation : GraphQLDirective + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLDirectiveWithComment : GraphQLDirective + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLDirectiveFull : GraphQLDirective { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -27,11 +49,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs b/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs index 4db3e61a..a27dcda1 100644 --- a/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs @@ -28,6 +28,28 @@ public class GraphQLDirectiveDefinition : GraphQLTypeDefinition public bool Repeatable { get; set; } } + internal sealed class GraphQLDirectiveDefinitionWithLocation : GraphQLDirectiveDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLDirectiveDefinitionWithComment : GraphQLDirectiveDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLDirectiveDefinitionFull : GraphQLDirectiveDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLDocument.cs b/src/GraphQLParser/AST/GraphQLDocument.cs index a334f9d7..c9eaea19 100644 --- a/src/GraphQLParser/AST/GraphQLDocument.cs +++ b/src/GraphQLParser/AST/GraphQLDocument.cs @@ -48,22 +48,45 @@ public void Dispose() } } - internal sealed class GraphQLDocumentFull : GraphQLDocument + internal sealed class GraphQLDocumentWithLocation : GraphQLDocument { private GraphQLLocation _location; - //private GraphQLComment? _comment; public override GraphQLLocation Location { get => _location; set => _location = value; } - - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} } + + //TODO: GraphQLDocument has no comments + + //internal sealed class GraphQLDocumentWithComment : GraphQLDocument + //{ + // private GraphQLComment? _comment; + + // public override GraphQLComment? Comment + // { + // get => _comment; + // set => _comment = value; + // } + //} + + //internal sealed class GraphQLDocumentFull : GraphQLDocument + //{ + // private GraphQLLocation _location; + // private GraphQLComment? _comment; + + // public override GraphQLLocation Location + // { + // get => _location; + // set => _location = value; + // } + + // public override GraphQLComment? Comment + // { + // get => _comment; + // set => _comment = value; + // } + //} } diff --git a/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs index 9fd18ad3..1d61d691 100644 --- a/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLEnumTypeDefinition.cs @@ -13,6 +13,28 @@ public class GraphQLEnumTypeDefinition : GraphQLTypeDefinition, IHasDirectivesNo public List? Values { get; set; } } + internal sealed class GraphQLEnumTypeDefinitionWithLocation : GraphQLEnumTypeDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLEnumTypeDefinitionWithComment : GraphQLEnumTypeDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLEnumTypeDefinitionFull : GraphQLEnumTypeDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs b/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs index 3dc28fb2..d7b3230f 100644 --- a/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLEnumValueDefinition.cs @@ -11,6 +11,28 @@ public class GraphQLEnumValueDefinition : GraphQLTypeDefinition, IHasDirectivesN public override ASTNodeKind Kind => ASTNodeKind.EnumValueDefinition; } + internal sealed class GraphQLEnumValueDefinitionWithLocation : GraphQLEnumValueDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLEnumValueDefinitionWithComment : GraphQLEnumValueDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLEnumValueDefinitionFull : GraphQLEnumValueDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLFieldDefinition.cs b/src/GraphQLParser/AST/GraphQLFieldDefinition.cs index 003041c9..f637d477 100644 --- a/src/GraphQLParser/AST/GraphQLFieldDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLFieldDefinition.cs @@ -15,6 +15,28 @@ public class GraphQLFieldDefinition : GraphQLTypeDefinition, IHasDirectivesNode public GraphQLType? Type { get; set; } } + internal sealed class GraphQLFieldDefinitionWithLocation : GraphQLFieldDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLFieldDefinitionWithComment : GraphQLFieldDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLFieldDefinitionFull : GraphQLFieldDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLFieldSelection.cs b/src/GraphQLParser/AST/GraphQLFieldSelection.cs index 4122b5b9..9641a2f2 100644 --- a/src/GraphQLParser/AST/GraphQLFieldSelection.cs +++ b/src/GraphQLParser/AST/GraphQLFieldSelection.cs @@ -20,6 +20,28 @@ public class GraphQLFieldSelection : ASTNode, IHasDirectivesNode, INamedNode public GraphQLSelectionSet? SelectionSet { get; set; } } + internal sealed class GraphQLFieldSelectionWithLocation : GraphQLFieldSelection + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLFieldSelectionWithComment : GraphQLFieldSelection + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLFieldSelectionFull : GraphQLFieldSelection { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLFragmentDefinition.cs b/src/GraphQLParser/AST/GraphQLFragmentDefinition.cs index bdfd7ae2..120d4040 100644 --- a/src/GraphQLParser/AST/GraphQLFragmentDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLFragmentDefinition.cs @@ -9,6 +9,27 @@ public class GraphQLFragmentDefinition : GraphQLInlineFragment, INamedNode public GraphQLName? Name { get; set; } } + internal sealed class GraphQLFragmentDefinitionWithLocation : GraphQLFragmentDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLFragmentDefinitionWithComment : GraphQLFragmentDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } internal sealed class GraphQLFragmentDefinitionFull : GraphQLFragmentDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLFragmentSpread.cs b/src/GraphQLParser/AST/GraphQLFragmentSpread.cs index 95524ca4..2604677d 100644 --- a/src/GraphQLParser/AST/GraphQLFragmentSpread.cs +++ b/src/GraphQLParser/AST/GraphQLFragmentSpread.cs @@ -14,6 +14,28 @@ public class GraphQLFragmentSpread : ASTNode, IHasDirectivesNode, INamedNode public GraphQLName? Name { get; set; } } + internal sealed class GraphQLFragmentSpreadWithLocation : GraphQLFragmentSpread + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLFragmentSpreadWithComment : GraphQLFragmentSpread + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLFragmentSpreadFull : GraphQLFragmentSpread { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLInlineFragment.cs b/src/GraphQLParser/AST/GraphQLInlineFragment.cs index 9ece5a4e..79c431d3 100644 --- a/src/GraphQLParser/AST/GraphQLInlineFragment.cs +++ b/src/GraphQLParser/AST/GraphQLInlineFragment.cs @@ -15,6 +15,28 @@ public class GraphQLInlineFragment : ASTNode, IHasDirectivesNode public GraphQLNamedType? TypeCondition { get; set; } } + internal sealed class GraphQLInlineFragmentWithLocation : GraphQLInlineFragment + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLInlineFragmentWithComment : GraphQLInlineFragment + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLInlineFragmentFull : GraphQLInlineFragment { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs index 02f7af8f..12a80d81 100644 --- a/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLInputObjectTypeDefinition.cs @@ -13,6 +13,28 @@ public class GraphQLInputObjectTypeDefinition : GraphQLTypeDefinition, IHasDirec public override ASTNodeKind Kind => ASTNodeKind.InputObjectTypeDefinition; } + internal sealed class GraphQLInputObjectTypeDefinitionWithLocation : GraphQLInputObjectTypeDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLInputObjectTypeDefinitionWithComment : GraphQLInputObjectTypeDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLInputObjectTypeDefinitionFull : GraphQLInputObjectTypeDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs b/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs index f5388c71..9f096589 100644 --- a/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLInputValueDefinition.cs @@ -15,6 +15,28 @@ public class GraphQLInputValueDefinition : GraphQLTypeDefinition, IHasDirectives public GraphQLType? Type { get; set; } } + internal sealed class GraphQLInputValueDefinitionWithLocation : GraphQLInputValueDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLInputValueDefinitionWithComment : GraphQLInputValueDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLInputValueDefinitionFull : GraphQLInputValueDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs index 7d78bfdd..577cfce8 100644 --- a/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLInterfaceTypeDefinition.cs @@ -13,6 +13,28 @@ public class GraphQLInterfaceTypeDefinition : GraphQLTypeDefinition, IHasDirecti public override ASTNodeKind Kind => ASTNodeKind.InterfaceTypeDefinition; } + internal sealed class GraphQLInterfaceTypeDefinitionWithLocation : GraphQLInterfaceTypeDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLInterfaceTypeDefinitionWithComment : GraphQLInterfaceTypeDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLInterfaceTypeDefinitionFull : GraphQLInterfaceTypeDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLListType.cs b/src/GraphQLParser/AST/GraphQLListType.cs index a0fbc780..9b3c70ec 100644 --- a/src/GraphQLParser/AST/GraphQLListType.cs +++ b/src/GraphQLParser/AST/GraphQLListType.cs @@ -11,10 +11,32 @@ public class GraphQLListType : GraphQLType public override string ToString() => $"[{Type}]"; } + internal sealed class GraphQLListTypeWithLocation : GraphQLListType + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLListTypeWithComment : GraphQLListType + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLListTypeFull : GraphQLListType { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -22,11 +44,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLListValue.cs b/src/GraphQLParser/AST/GraphQLListValue.cs index 15f169ad..4b65e5bb 100644 --- a/src/GraphQLParser/AST/GraphQLListValue.cs +++ b/src/GraphQLParser/AST/GraphQLListValue.cs @@ -22,10 +22,42 @@ public GraphQLListValue(ASTNodeKind kind) public override string ToString() => AstValue.ToString(); } + internal sealed class GraphQLListValueWithLocation : GraphQLListValue + { + private GraphQLLocation _location; + + public GraphQLListValueWithLocation(ASTNodeKind kind) + : base(kind) + { + } + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLListValueWithComment : GraphQLListValue + { + private GraphQLComment? _comment; + + public GraphQLListValueWithComment(ASTNodeKind kind) + : base(kind) + { + } + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLListValueFull : GraphQLListValue { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public GraphQLListValueFull(ASTNodeKind kind) : base(kind) @@ -38,11 +70,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLName.cs b/src/GraphQLParser/AST/GraphQLName.cs index fa88454b..2a64ddb2 100644 --- a/src/GraphQLParser/AST/GraphQLName.cs +++ b/src/GraphQLParser/AST/GraphQLName.cs @@ -15,10 +15,32 @@ public class GraphQLName : ASTNode public ROM Value { get; set; } } + internal sealed class GraphQLNameWithLocation : GraphQLName + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLNameWithComment : GraphQLName + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLNameFull : GraphQLName { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -26,11 +48,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLNamedType.cs b/src/GraphQLParser/AST/GraphQLNamedType.cs index dfd3e225..836c77db 100644 --- a/src/GraphQLParser/AST/GraphQLNamedType.cs +++ b/src/GraphQLParser/AST/GraphQLNamedType.cs @@ -12,10 +12,32 @@ public class GraphQLNamedType : GraphQLType, INamedNode public override string ToString() => Name?.Value.ToString()!; } + internal sealed class GraphQLNamedTypeWithLocation : GraphQLNamedType + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLNamedTypeWithComment : GraphQLNamedType + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLNamedTypeFull : GraphQLNamedType { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -23,11 +45,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLNonNullType.cs b/src/GraphQLParser/AST/GraphQLNonNullType.cs index c47b9c19..8c746356 100644 --- a/src/GraphQLParser/AST/GraphQLNonNullType.cs +++ b/src/GraphQLParser/AST/GraphQLNonNullType.cs @@ -11,10 +11,32 @@ public class GraphQLNonNullType : GraphQLType public override string ToString() => Type + "!"; } + internal sealed class GraphQLNonNullTypeWithLocation : GraphQLNonNullType + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLNonNullTypeWithComment : GraphQLNonNullType + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLNonNullTypeFull : GraphQLNonNullType { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -22,11 +44,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLObjectField.cs b/src/GraphQLParser/AST/GraphQLObjectField.cs index 92733a79..04183bf5 100644 --- a/src/GraphQLParser/AST/GraphQLObjectField.cs +++ b/src/GraphQLParser/AST/GraphQLObjectField.cs @@ -11,6 +11,28 @@ public class GraphQLObjectField : ASTNode, INamedNode public GraphQLValue? Value { get; set; } } + internal sealed class GraphQLObjectFieldWithLocation : GraphQLObjectField + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLObjectFieldWithComment : GraphQLObjectField + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLObjectFieldFull : GraphQLObjectField { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs index 708cd948..5a55d18e 100644 --- a/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLObjectTypeDefinition.cs @@ -15,6 +15,28 @@ public class GraphQLObjectTypeDefinition : GraphQLTypeDefinition, IHasDirectives public override ASTNodeKind Kind => ASTNodeKind.ObjectTypeDefinition; } + internal sealed class GraphQLObjectTypeDefinitionWithLocation : GraphQLObjectTypeDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLObjectTypeDefinitionWithComment : GraphQLObjectTypeDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLObjectTypeDefinitionFull : GraphQLObjectTypeDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLObjectValue.cs b/src/GraphQLParser/AST/GraphQLObjectValue.cs index c42aaa7c..fd1f04ce 100644 --- a/src/GraphQLParser/AST/GraphQLObjectValue.cs +++ b/src/GraphQLParser/AST/GraphQLObjectValue.cs @@ -10,6 +10,28 @@ public class GraphQLObjectValue : GraphQLValue public override ASTNodeKind Kind => ASTNodeKind.ObjectValue; } + internal sealed class GraphQLObjectValueWithLocation : GraphQLObjectValue + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLObjectValueWithComment : GraphQLObjectValue + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLObjectValueFull : GraphQLObjectValue { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLOperationDefinition.cs b/src/GraphQLParser/AST/GraphQLOperationDefinition.cs index 47e12466..f91df112 100644 --- a/src/GraphQLParser/AST/GraphQLOperationDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLOperationDefinition.cs @@ -20,6 +20,28 @@ public class GraphQLOperationDefinition : ASTNode, IHasDirectivesNode, INamedNod public List? VariableDefinitions { get; set; } } + internal sealed class GraphQLOperationDefinitionWithLocation : GraphQLOperationDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLOperationDefinitionWithComment : GraphQLOperationDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLOperationDefinitionFull : GraphQLOperationDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLOperationTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLOperationTypeDefinition.cs index 7661052b..f856f5a3 100644 --- a/src/GraphQLParser/AST/GraphQLOperationTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLOperationTypeDefinition.cs @@ -10,10 +10,32 @@ public class GraphQLOperationTypeDefinition : ASTNode public GraphQLNamedType? Type { get; set; } } + internal sealed class GraphQLOperationTypeDefinitionWithLocation : GraphQLOperationTypeDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLOperationTypeDefinitionWithComment : GraphQLOperationTypeDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLOperationTypeDefinitionFull : GraphQLOperationTypeDefinition { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -21,11 +43,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs index 00d91e98..96048ade 100644 --- a/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLScalarTypeDefinition.cs @@ -11,6 +11,28 @@ public class GraphQLScalarTypeDefinition : GraphQLTypeDefinition, IHasDirectives public override ASTNodeKind Kind => ASTNodeKind.ScalarTypeDefinition; } + internal sealed class GraphQLScalarTypeDefinitionWithLocation : GraphQLScalarTypeDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLScalarTypeDefinitionWithComment : GraphQLScalarTypeDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLScalarTypeDefinitionFull : GraphQLScalarTypeDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLScalarValue.cs b/src/GraphQLParser/AST/GraphQLScalarValue.cs index fb0237cb..4fae7501 100644 --- a/src/GraphQLParser/AST/GraphQLScalarValue.cs +++ b/src/GraphQLParser/AST/GraphQLScalarValue.cs @@ -45,10 +45,42 @@ public GraphQLScalarValue(ASTNodeKind kind) public override string? ToString() => Kind == ASTNodeKind.StringValue ? $"\"{Value}\"" : Value.ToString(); } + internal sealed class GraphQLScalarValueWithLocation : GraphQLScalarValue + { + private GraphQLLocation _location; + + public GraphQLScalarValueWithLocation(ASTNodeKind kind) + : base(kind) + { + } + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLScalarValueWithComment : GraphQLScalarValue + { + private GraphQLComment? _comment; + + public GraphQLScalarValueWithComment(ASTNodeKind kind) + : base(kind) + { + } + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLScalarValueFull : GraphQLScalarValue { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public GraphQLScalarValueFull(ASTNodeKind kind) : base(kind) @@ -61,11 +93,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs b/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs index 4096930d..e68d2b2a 100644 --- a/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs @@ -16,6 +16,28 @@ public class GraphQLSchemaDefinition : ASTNode, IHasDirectivesNode, IHasDescript public List? OperationTypes { get; set; } } + internal sealed class GraphQLSchemaDefinitionWithLocation : GraphQLSchemaDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLSchemaDefinitionWithComment : GraphQLSchemaDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLSchemaDefinitionFull : GraphQLSchemaDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLSelectionSet.cs b/src/GraphQLParser/AST/GraphQLSelectionSet.cs index 92f7c8e9..8b4ba21f 100644 --- a/src/GraphQLParser/AST/GraphQLSelectionSet.cs +++ b/src/GraphQLParser/AST/GraphQLSelectionSet.cs @@ -10,10 +10,32 @@ public class GraphQLSelectionSet : ASTNode public List? Selections { get; set; } } + internal sealed class GraphQLSelectionSetWithLocation : GraphQLSelectionSet + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLSelectionSetWithComment : GraphQLSelectionSet + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLSelectionSetFull : GraphQLSelectionSet { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -21,11 +43,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLTypeExtensionDefinition.cs b/src/GraphQLParser/AST/GraphQLTypeExtensionDefinition.cs index 5a64ef88..e6f96760 100644 --- a/src/GraphQLParser/AST/GraphQLTypeExtensionDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLTypeExtensionDefinition.cs @@ -8,6 +8,28 @@ public class GraphQLTypeExtensionDefinition : GraphQLTypeDefinition public override ASTNodeKind Kind => ASTNodeKind.TypeExtensionDefinition; } + internal sealed class GraphQLTypeExtensionDefinitionWithLocation : GraphQLTypeExtensionDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLTypeExtensionDefinitionWithComment : GraphQLTypeExtensionDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLTypeExtensionDefinitionFull : GraphQLTypeExtensionDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs index 3ee86ab5..cc88601c 100644 --- a/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLUnionTypeDefinition.cs @@ -13,6 +13,28 @@ public class GraphQLUnionTypeDefinition : GraphQLTypeDefinition, IHasDirectivesN public List? Types { get; set; } } + internal sealed class GraphQLUnionTypeDefinitionWithLocation : GraphQLUnionTypeDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLUnionTypeDefinitionWithComment : GraphQLUnionTypeDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLUnionTypeDefinitionFull : GraphQLUnionTypeDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/AST/GraphQLVariable.cs b/src/GraphQLParser/AST/GraphQLVariable.cs index 0e4efe96..5dba68f1 100644 --- a/src/GraphQLParser/AST/GraphQLVariable.cs +++ b/src/GraphQLParser/AST/GraphQLVariable.cs @@ -9,10 +9,32 @@ public class GraphQLVariable : GraphQLValue, INamedNode public GraphQLName? Name { get; set; } } + internal sealed class GraphQLVariableWithLocation : GraphQLVariable + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLVariableWithComment : GraphQLVariable + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } + internal sealed class GraphQLVariableFull : GraphQLVariable { private GraphQLLocation _location; - //private GraphQLComment? _comment; + private GraphQLComment? _comment; public override GraphQLLocation Location { @@ -20,11 +42,10 @@ public override GraphQLLocation Location set => _location = value; } - // TODO: this property is not set anywhere (yet), so it makes no sense to create a field for it - //public override GraphQLComment? Comment - //{ - // get => _comment; - // set => _comment = value; - //} + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } } } diff --git a/src/GraphQLParser/AST/GraphQLVariableDefinition.cs b/src/GraphQLParser/AST/GraphQLVariableDefinition.cs index 666424b7..2da67930 100644 --- a/src/GraphQLParser/AST/GraphQLVariableDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLVariableDefinition.cs @@ -12,6 +12,27 @@ public class GraphQLVariableDefinition : ASTNode public GraphQLVariable? Variable { get; set; } } + internal sealed class GraphQLVariableDefinitionWithLocation : GraphQLVariableDefinition + { + private GraphQLLocation _location; + + public override GraphQLLocation Location + { + get => _location; + set => _location = value; + } + } + + internal sealed class GraphQLVariableDefinitionWithComment : GraphQLVariableDefinition + { + private GraphQLComment? _comment; + + public override GraphQLComment? Comment + { + get => _comment; + set => _comment = value; + } + } internal sealed class GraphQLVariableDefinitionFull : GraphQLVariableDefinition { private GraphQLLocation _location; diff --git a/src/GraphQLParser/IgnoreOptions.cs b/src/GraphQLParser/IgnoreOptions.cs index ea035167..db1743de 100644 --- a/src/GraphQLParser/IgnoreOptions.cs +++ b/src/GraphQLParser/IgnoreOptions.cs @@ -19,7 +19,7 @@ public enum IgnoreOptions Comments = 1, /// - /// Specifies whether to ignore token locations when parsing GraphQL document. + /// Specifies whether to ignore token locations when parsing GraphQL document. /// Locations = 2, diff --git a/src/GraphQLParser/NodeHelper.cs b/src/GraphQLParser/NodeHelper.cs new file mode 100644 index 00000000..8ad4765f --- /dev/null +++ b/src/GraphQLParser/NodeHelper.cs @@ -0,0 +1,416 @@ +using System.Runtime.CompilerServices; +using GraphQLParser.AST; + +namespace GraphQLParser +{ + internal static class NodeHelper + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLComment CreateGraphQLComment(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLComment(), + IgnoreOptions.Comments => new GraphQLCommentWithLocation(), + IgnoreOptions.Locations => new GraphQLComment(), + _ => new GraphQLCommentWithLocation(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLDocument CreateGraphQLDocument(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLDocument(), + IgnoreOptions.Comments => new GraphQLDocumentWithLocation(), + IgnoreOptions.Locations => new GraphQLDocument(), + _ => new GraphQLDocumentWithLocation(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLDescription CreateGraphQLDescription(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLDescription(), + IgnoreOptions.Comments => new GraphQLDescriptionWithLocation(), + IgnoreOptions.Locations => new GraphQLDescription(), + _ => new GraphQLDescriptionWithLocation(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLArgument CreateGraphQLArgument(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLArgument(), + IgnoreOptions.Comments => new GraphQLArgumentWithLocation(), + IgnoreOptions.Locations => new GraphQLArgumentWithComment(), + _ => new GraphQLArgumentFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLDirective CreateGraphQLDirective(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLDirective(), + IgnoreOptions.Comments => new GraphQLDirectiveWithLocation(), + IgnoreOptions.Locations => new GraphQLDirectiveWithComment(), + _ => new GraphQLDirectiveFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLVariableDefinition CreateGraphQLVariableDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLVariableDefinition(), + IgnoreOptions.Comments => new GraphQLVariableDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLVariableDefinitionWithComment(), + _ => new GraphQLVariableDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLEnumTypeDefinition CreateGraphQLEnumTypeDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLEnumTypeDefinition(), + IgnoreOptions.Comments => new GraphQLEnumTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLEnumTypeDefinitionWithComment(), + _ => new GraphQLEnumTypeDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLScalarValue CreateGraphQLScalarValue(IgnoreOptions options, ASTNodeKind kind) + { + return options switch + { + IgnoreOptions.All => new GraphQLScalarValue(kind), + IgnoreOptions.Comments => new GraphQLScalarValueWithLocation(kind), + IgnoreOptions.Locations => new GraphQLScalarValueWithComment(kind), + _ => new GraphQLScalarValueFull(kind), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLEnumValueDefinition CreateGraphQLEnumValueDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLEnumValueDefinition(), + IgnoreOptions.Comments => new GraphQLEnumValueDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLEnumValueDefinitionWithComment(), + _ => new GraphQLEnumValueDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLFieldDefinition CreateGraphQLFieldDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLFieldDefinition(), + IgnoreOptions.Comments => new GraphQLFieldDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLFieldDefinitionWithComment(), + _ => new GraphQLFieldDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLSelectionSet CreateGraphQLSelectionSet(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLSelectionSet(), + IgnoreOptions.Comments => new GraphQLSelectionSetWithLocation(), + IgnoreOptions.Locations => new GraphQLSelectionSetWithComment(), + _ => new GraphQLSelectionSetFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLVariable CreateGraphQLVariable(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLVariable(), + IgnoreOptions.Comments => new GraphQLVariableWithLocation(), + IgnoreOptions.Locations => new GraphQLVariableWithComment(), + _ => new GraphQLVariableFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLOperationTypeDefinition CreateGraphQLOperationTypeDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLOperationTypeDefinition(), + IgnoreOptions.Comments => new GraphQLOperationTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLOperationTypeDefinitionWithComment(), + _ => new GraphQLOperationTypeDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLNamedType CreateGraphQLNamedType(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLNamedType(), + IgnoreOptions.Comments => new GraphQLNamedTypeWithLocation(), + IgnoreOptions.Locations => new GraphQLNamedTypeWithComment(), + _ => new GraphQLNamedTypeFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLName CreateGraphQLName(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLName(), + IgnoreOptions.Comments => new GraphQLNameWithLocation(), + IgnoreOptions.Locations => new GraphQLNameWithComment(), + _ => new GraphQLNameFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLListValue CreateGraphQLListValue(IgnoreOptions options, ASTNodeKind kind) + { + return options switch + { + IgnoreOptions.All => new GraphQLListValue(kind), + IgnoreOptions.Comments => new GraphQLListValueWithLocation(kind), + IgnoreOptions.Locations => new GraphQLListValueWithComment(kind), + _ => new GraphQLListValueFull(kind), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLListType CreateGraphQLListType(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLListType(), + IgnoreOptions.Comments => new GraphQLListTypeWithLocation(), + IgnoreOptions.Locations => new GraphQLListTypeWithComment(), + _ => new GraphQLListTypeFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLDirectiveDefinition CreateGraphQLDirectiveDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLDirectiveDefinition(), + IgnoreOptions.Comments => new GraphQLDirectiveDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLDirectiveDefinitionWithComment(), + _ => new GraphQLDirectiveDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLFieldSelection CreateGraphQLFieldSelection(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLFieldSelection(), + IgnoreOptions.Comments => new GraphQLFieldSelectionWithLocation(), + IgnoreOptions.Locations => new GraphQLFieldSelectionWithComment(), + _ => new GraphQLFieldSelectionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLFragmentDefinition CreateGraphQLFragmentDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLFragmentDefinition(), + IgnoreOptions.Comments => new GraphQLFragmentDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLFragmentDefinitionWithComment(), + _ => new GraphQLFragmentDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLUnionTypeDefinition CreateGraphQLUnionTypeDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLUnionTypeDefinition(), + IgnoreOptions.Comments => new GraphQLUnionTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLUnionTypeDefinitionWithComment(), + _ => new GraphQLUnionTypeDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLTypeExtensionDefinition CreateGraphQLTypeExtensionDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLTypeExtensionDefinition(), + IgnoreOptions.Comments => new GraphQLTypeExtensionDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLTypeExtensionDefinitionWithComment(), + _ => new GraphQLTypeExtensionDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLFragmentSpread CreateGraphQLFragmentSpread(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLFragmentSpread(), + IgnoreOptions.Comments => new GraphQLFragmentSpreadWithLocation(), + IgnoreOptions.Locations => new GraphQLFragmentSpreadWithComment(), + _ => new GraphQLFragmentSpreadFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLInlineFragment CreateGraphQLInlineFragment(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLInlineFragment(), + IgnoreOptions.Comments => new GraphQLInlineFragmentWithLocation(), + IgnoreOptions.Locations => new GraphQLInlineFragmentWithComment(), + _ => new GraphQLInlineFragmentFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLInputObjectTypeDefinition CreateGraphQLInputObjectTypeDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLInputObjectTypeDefinition(), + IgnoreOptions.Comments => new GraphQLInputObjectTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLInputObjectTypeDefinitionWithComment(), + _ => new GraphQLInputObjectTypeDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLInterfaceTypeDefinition CreateGraphQLInterfaceTypeDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLInterfaceTypeDefinition(), + IgnoreOptions.Comments => new GraphQLInterfaceTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLInterfaceTypeDefinitionWithComment(), + _ => new GraphQLInterfaceTypeDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLNonNullType CreateGraphQLNonNullType(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLNonNullType(), + IgnoreOptions.Comments => new GraphQLNonNullTypeWithLocation(), + IgnoreOptions.Locations => new GraphQLNonNullTypeWithComment(), + _ => new GraphQLNonNullTypeFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLSchemaDefinition CreateGraphQLSchemaDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLSchemaDefinition(), + IgnoreOptions.Comments => new GraphQLSchemaDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLSchemaDefinitionWithComment(), + _ => new GraphQLSchemaDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLScalarTypeDefinition CreateGraphQLScalarTypeDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLScalarTypeDefinition(), + IgnoreOptions.Comments => new GraphQLScalarTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLScalarTypeDefinitionWithComment(), + _ => new GraphQLScalarTypeDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLOperationDefinition CreateGraphQLOperationDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLOperationDefinition(), + IgnoreOptions.Comments => new GraphQLOperationDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLOperationDefinitionWithComment(), + _ => new GraphQLOperationDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLObjectTypeDefinition CreateGraphQLObjectTypeDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLObjectTypeDefinition(), + IgnoreOptions.Comments => new GraphQLObjectTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLObjectTypeDefinitionWithComment(), + _ => new GraphQLObjectTypeDefinitionFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLObjectField CreateGraphQLObjectField(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLObjectField(), + IgnoreOptions.Comments => new GraphQLObjectFieldWithLocation(), + IgnoreOptions.Locations => new GraphQLObjectFieldWithComment(), + _ => new GraphQLObjectFieldFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLObjectValue CreateGraphQLObjectValue(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLObjectValue(), + IgnoreOptions.Comments => new GraphQLObjectValueWithLocation(), + IgnoreOptions.Locations => new GraphQLObjectValueWithComment(), + _ => new GraphQLObjectValueFull(), + }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static GraphQLInputValueDefinition CreateGraphQLInputValueDefinition(IgnoreOptions options) + { + return options switch + { + IgnoreOptions.All => new GraphQLInputValueDefinition(), + IgnoreOptions.Comments => new GraphQLInputValueDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLInputValueDefinitionWithComment(), + _ => new GraphQLInputValueDefinitionFull(), + }; + } + } +} diff --git a/src/GraphQLParser/ParserContext.Parse.cs b/src/GraphQLParser/ParserContext.Parse.cs index 62481fa1..af3715f9 100644 --- a/src/GraphQLParser/ParserContext.Parse.cs +++ b/src/GraphQLParser/ParserContext.Parse.cs @@ -7,13 +7,6 @@ namespace GraphQLParser // WARNING: mutable struct, pass it by reference to those methods that will change it internal partial struct ParserContext { - public GraphQLComment? GetComment() - { - var ret = _currentComment; - _currentComment = null; - return ret; - } - public GraphQLDocument Parse() => ParseDocument(); private GraphQLNamedType? ParseTypeCondition() @@ -30,22 +23,15 @@ internal partial struct ParserContext private GraphQLArgument ParseArgument() { - var comment = GetComment(); int start = _currentToken.Start; + var comment = GetComment(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLArgument - { - Name = ParseName(), - Value = ExpectColonAndParseValueLiteral(false), - } - : new GraphQLArgumentFull - { - Comment = comment, - Name = ParseName(), - Value = ExpectColonAndParseValueLiteral(false), - Location = GetLocation(start) - }; + var arg = NodeHelper.CreateGraphQLArgument(_ignoreOptions); + arg.Name = ParseName(); + arg.Value = ExpectColonAndParseValueLiteral(false); + arg.Comment = comment; + arg.Location = GetLocation(start); + return arg; } private List? ParseArgumentDefs() @@ -85,17 +71,14 @@ private GraphQLArgument ParseArgument() private GraphQLValue ParseBooleanValue(Token token) { + var comment = GetComment(); Advance(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLScalarValue(ASTNodeKind.BooleanValue) - { - Value = token.Value, - } - : new GraphQLScalarValueFull(ASTNodeKind.BooleanValue) - { - Value = token.Value, - Location = GetLocation(token.Start) - }; + + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.BooleanValue); + val.Value = token.Value; + val.Comment = comment; + val.Location = GetLocation(token.Start); + return val; } private ASTNode ParseDefinition() @@ -174,12 +157,8 @@ private List ParseDefinitionsIfNotEOF() } while (_currentToken.Kind == TokenKind.COMMENT); - var comment = _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLComment() - : new GraphQLCommentFull - { - Location = new GraphQLLocation(start, end), - }; + var comment = NodeHelper.CreateGraphQLComment(_ignoreOptions); + comment.Location = new GraphQLLocation(start, end); if (text.Count == 1) { @@ -205,22 +184,24 @@ private void SetCurrentComment(GraphQLComment? comment) _currentComment = comment; } + private GraphQLComment? GetComment() + { + var ret = _currentComment; + _currentComment = null; + return ret; + } + private GraphQLDirective ParseDirective() { int start = _currentToken.Start; Expect(TokenKind.AT); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLDirective - { - Name = ParseName(), - Arguments = ParseArguments(), - } - : new GraphQLDirectiveFull - { - Name = ParseName(), - Arguments = ParseArguments(), - Location = GetLocation(start) - }; + + var dir = NodeHelper.CreateGraphQLDirective(_ignoreOptions); + dir.Name = ParseName(); + dir.Arguments = ParseArguments(); + dir.Comment = null; //TODO: ???? + dir.Location = GetLocation(start); + return dir; } /// @@ -249,25 +230,15 @@ private GraphQLDirectiveDefinition ParseDirectiveDefinition() ExpectKeyword("on"); var locations = ParseDirectiveLocations(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLDirectiveDefinition - { - Name = name, - Repeatable = repeatable, - Arguments = args, - Locations = locations, - Description = description, - } - : new GraphQLDirectiveDefinitionFull - { - Comment = comment, - Name = name, - Repeatable = repeatable, - Arguments = args, - Locations = locations, - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLDirectiveDefinition(_ignoreOptions); + def.Name = name; + def.Repeatable = repeatable; + def.Arguments = args; + def.Locations = locations; + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private bool ParseRepeatable() @@ -322,24 +293,21 @@ private List ParseDirectiveLocations() private GraphQLDocument ParseDocument() { - _document = _ignoreOptions.HasFlag(IgnoreOptions.Locations) ? new GraphQLDocument() : new GraphQLDocumentFull(); + _document = NodeHelper.CreateGraphQLDocument(_ignoreOptions); int start = _currentToken.Start; var definitions = ParseDefinitionsIfNotEOF(); SetCurrentComment(null); - if (!_ignoreOptions.HasFlag(IgnoreOptions.Locations)) - { - _document.Location = new GraphQLLocation - ( - start, - // Formally, to denote the end of the document, it is better to use _prevToken.End, - // since _prevToken represents some real meaningful token; _currentToken here is always EOF. - // EOF is a technical token with length = 0, _prevToken.End and _currentToken.End have the same value here. - _prevToken.End // equals to _currentToken.End (EOF) - ); - } + _document.Location = new GraphQLLocation + ( + start, + // Formally, to denote the end of the document, it is better to use _prevToken.End, + // since _prevToken represents some real meaningful token; _currentToken here is always EOF. + // EOF is a technical token with length = 0, _prevToken.End and _currentToken.End have the same value here. + _prevToken.End // equals to _currentToken.End (EOF) + ); _document.Definitions = definitions; _document.UnattachedComments = _unattachedComments; return _document; @@ -357,38 +325,26 @@ private GraphQLEnumTypeDefinition ParseEnumTypeDefinition() var comment = GetComment(); ExpectKeyword("enum"); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLEnumTypeDefinition - { - Name = ParseName(), - Directives = ParseDirectives(), - Values = ParseEnumValueDefinitions(), - Description = description, - } - : new GraphQLEnumTypeDefinitionFull - { - Comment = comment, - Name = ParseName(), - Directives = ParseDirectives(), - Values = ParseEnumValueDefinitions(), - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLEnumTypeDefinition(_ignoreOptions); + def.Name = ParseName(); + def.Directives = ParseDirectives(); + def.Values = ParseEnumValueDefinitions(); + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLValue ParseEnumValue(Token token) { + var comment = GetComment(); Advance(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLScalarValue(ASTNodeKind.EnumValue) - { - Value = token.Value, - } - : new GraphQLScalarValueFull(ASTNodeKind.EnumValue) - { - Value = token.Value, - Location = GetLocation(token.Start) - }; + + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.EnumValue); + val.Value = token.Value; + val.Comment = comment; + val.Location = GetLocation(token.Start); + return val; } private GraphQLEnumValueDefinition ParseEnumValueDefinition() @@ -402,21 +358,13 @@ private GraphQLEnumValueDefinition ParseEnumValueDefinition() } var comment = GetComment(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLEnumValueDefinition - { - Name = ParseName(), - Directives = ParseDirectives(), - Description = description, - } - : new GraphQLEnumValueDefinitionFull - { - Comment = comment, - Name = ParseName(), - Directives = ParseDirectives(), - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLEnumValueDefinition(_ignoreOptions); + def.Name = ParseName(); + def.Directives = ParseDirectives(); + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLFieldDefinition ParseFieldDefinition() @@ -434,31 +382,21 @@ private GraphQLFieldDefinition ParseFieldDefinition() var args = ParseArgumentDefs(); Expect(TokenKind.COLON); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLFieldDefinition - { - Name = name, - Arguments = args, - Type = ParseType(), - Directives = ParseDirectives(), - Description = description, - } - : new GraphQLFieldDefinitionFull - { - Comment = comment, - Name = name, - Arguments = args, - Type = ParseType(), - Directives = ParseDirectives(), - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLFieldDefinition(_ignoreOptions); + def.Name = name; + def.Arguments = args; + def.Type = ParseType(); + def.Directives = ParseDirectives(); + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLFieldSelection ParseFieldSelection() { - var comment = GetComment(); int start = _currentToken.Start; + var comment = GetComment(); var nameOrAlias = ParseName(); GraphQLName name; GraphQLName? alias; @@ -474,47 +412,34 @@ private GraphQLFieldSelection ParseFieldSelection() name = nameOrAlias; } - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLFieldSelection - { - Alias = alias, - Name = name, - Arguments = ParseArguments(), - Directives = ParseDirectives(), - SelectionSet = Peek(TokenKind.BRACE_L) ? ParseSelectionSet() : null, - } - : new GraphQLFieldSelectionFull - { - Comment = comment, - Alias = alias, - Name = name, - Arguments = ParseArguments(), - Directives = ParseDirectives(), - SelectionSet = Peek(TokenKind.BRACE_L) ? ParseSelectionSet() : null, - Location = GetLocation(start) - }; + var sel = NodeHelper.CreateGraphQLFieldSelection(_ignoreOptions); + sel.Alias = alias; + sel.Name = name; + sel.Arguments = ParseArguments(); + sel.Directives = ParseDirectives(); + sel.SelectionSet = Peek(TokenKind.BRACE_L) ? ParseSelectionSet() : null; + sel.Comment = comment; + sel.Location = GetLocation(start); + return sel; } private GraphQLValue ParseFloat(/*bool isConstant*/) { var token = _currentToken; + var comment = GetComment(); Advance(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLScalarValue(ASTNodeKind.FloatValue) - { - Value = token.Value, - } - : new GraphQLScalarValueFull(ASTNodeKind.FloatValue) - { - Value = token.Value, - Location = GetLocation(token.Start) - }; + + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.FloatValue); + val.Value = token.Value; + val.Comment = comment; + val.Location = GetLocation(token.Start); + return val; } private ASTNode ParseFragment() { - var comment = GetComment(); int start = _currentToken.Start; + var comment = GetComment(); Expect(TokenKind.SPREAD); return Peek(TokenKind.NAME) && _currentToken.Value != "on" @@ -524,63 +449,39 @@ private ASTNode ParseFragment() private ASTNode CreateGraphQLFragmentSpread(int start, GraphQLComment? comment) { - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLFragmentSpread - { - Name = ParseFragmentName(), - Directives = ParseDirectives(), - } - : new GraphQLFragmentSpreadFull - { - Comment = comment, - Name = ParseFragmentName(), - Directives = ParseDirectives(), - Location = GetLocation(start) - }; + var spread = NodeHelper.CreateGraphQLFragmentSpread(_ignoreOptions); + spread.Name = ParseFragmentName(); + spread.Directives = ParseDirectives(); + spread.Comment = comment; + spread.Location = GetLocation(start); + return spread; } private ASTNode CreateInlineFragment(int start, GraphQLComment? comment) { - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLInlineFragment - { - TypeCondition = ParseTypeCondition(), - Directives = ParseDirectives(), - SelectionSet = ParseSelectionSet(), - } - : new GraphQLInlineFragmentFull - { - Comment = comment, - TypeCondition = ParseTypeCondition(), - Directives = ParseDirectives(), - SelectionSet = ParseSelectionSet(), - Location = GetLocation(start) - }; + var frag = NodeHelper.CreateGraphQLInlineFragment(_ignoreOptions); + frag.TypeCondition = ParseTypeCondition(); + frag.Directives = ParseDirectives(); + frag.SelectionSet = ParseSelectionSet(); + frag.Comment = comment; + frag.Location = GetLocation(start); + return frag; } private GraphQLFragmentDefinition ParseFragmentDefinition() { - var comment = GetComment(); int start = _currentToken.Start; + var comment = GetComment(); ExpectKeyword("fragment"); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLFragmentDefinition - { - Name = ParseFragmentName(), - TypeCondition = ExpectOnKeywordAndParseNamedType(), - Directives = ParseDirectives(), - SelectionSet = ParseSelectionSet(), - } - : new GraphQLFragmentDefinitionFull - { - Comment = comment, - Name = ParseFragmentName(), - TypeCondition = ExpectOnKeywordAndParseNamedType(), - Directives = ParseDirectives(), - SelectionSet = ParseSelectionSet(), - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLFragmentDefinition(_ignoreOptions); + def.Name = ParseFragmentName(); + def.TypeCondition = ExpectOnKeywordAndParseNamedType(); + def.Directives = ParseDirectives(); + def.SelectionSet = ParseSelectionSet(); + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLName ParseFragmentName() @@ -632,23 +533,14 @@ private GraphQLInputObjectTypeDefinition ParseInputObjectTypeDefinition() var comment = GetComment(); ExpectKeyword("input"); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLInputObjectTypeDefinition - { - Name = ParseName(), - Directives = ParseDirectives(), - Fields = ParseInputValueDefs(), - Description = description, - } - : new GraphQLInputObjectTypeDefinitionFull - { - Comment = comment, - Name = ParseName(), - Directives = ParseDirectives(), - Fields = ParseInputValueDefs(), - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLInputObjectTypeDefinition(_ignoreOptions); + def.Name = ParseName(); + def.Directives = ParseDirectives(); + def.Fields = ParseInputValueDefs(); + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLInputValueDefinition ParseInputValueDef() @@ -664,42 +556,28 @@ private GraphQLInputValueDefinition ParseInputValueDef() var name = ParseName(); Expect(TokenKind.COLON); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLInputValueDefinition - { - Name = name, - Type = ParseType(), - DefaultValue = Skip(TokenKind.EQUALS) ? ParseValueLiteral(true) : null, - Directives = ParseDirectives(), - Description = description, - } - : new GraphQLInputValueDefinitionFull - { - Comment = comment, - Name = name, - Type = ParseType(), - DefaultValue = Skip(TokenKind.EQUALS) ? ParseValueLiteral(true) : null, - Directives = ParseDirectives(), - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLInputValueDefinition(_ignoreOptions); + def.Name = name; + def.Type = ParseType(); + def.DefaultValue = Skip(TokenKind.EQUALS) ? ParseValueLiteral(true) : null; + def.Directives = ParseDirectives(); + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLValue ParseInt(/*bool isConstant*/) { var token = _currentToken; + var comment = GetComment(); Advance(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLScalarValue(ASTNodeKind.IntValue) - { - Value = token.Value, - } - : new GraphQLScalarValueFull(ASTNodeKind.IntValue) - { - Value = token.Value, - Location = GetLocation(token.Start) - }; + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.IntValue); + val.Value = token.Value; + val.Comment = comment; + val.Location = GetLocation(token.Start); + return val; } private GraphQLInterfaceTypeDefinition ParseInterfaceTypeDefinition() @@ -714,63 +592,46 @@ private GraphQLInterfaceTypeDefinition ParseInterfaceTypeDefinition() var comment = GetComment(); ExpectKeyword("interface"); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLInterfaceTypeDefinition - { - Name = ParseName(), - Directives = ParseDirectives(), - Fields = ParseFieldDefinitions(), - Description = description, - } - : new GraphQLInterfaceTypeDefinitionFull - { - Comment = comment, - Name = ParseName(), - Directives = ParseDirectives(), - Fields = ParseFieldDefinitions(), - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLInterfaceTypeDefinition(_ignoreOptions); + def.Name = ParseName(); + def.Directives = ParseDirectives(); + def.Fields = ParseFieldDefinitions(); + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLValue ParseList(bool isConstant) { int start = _currentToken.Start; + var comment = GetComment(); + // the compiler caches these delegates in the generated code ParseCallback constant = (ref ParserContext context) => context.ParseValueLiteral(true); ParseCallback value = (ref ParserContext context) => context.ParseValueLiteral(false); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLListValue(ASTNodeKind.ListValue) - { - Values = ZeroOrMore(TokenKind.BRACKET_L, isConstant ? constant : value, TokenKind.BRACKET_R), - AstValue = _source.Slice(start, _currentToken.End - start - 1) - } - : new GraphQLListValueFull(ASTNodeKind.ListValue) - { - Values = ZeroOrMore(TokenKind.BRACKET_L, isConstant ? constant : value, TokenKind.BRACKET_R), - Location = GetLocation(start), - AstValue = _source.Slice(start, _currentToken.End - start - 1) - }; + var val = NodeHelper.CreateGraphQLListValue(_ignoreOptions, ASTNodeKind.ListValue); + val.Values = ZeroOrMore(TokenKind.BRACKET_L, isConstant ? constant : value, TokenKind.BRACKET_R); + val.AstValue = _source.Slice(start, _currentToken.End - start - 1); + val.Comment = comment; + val.Location = GetLocation(start); + return val; } private GraphQLName ParseName() { int start = _currentToken.Start; var value = _currentToken.Value; + var comment = GetComment(); Expect(TokenKind.NAME); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLName - { - Value = value - } - : new GraphQLNameFull - { - Location = GetLocation(start), - Value = value - }; + var n = NodeHelper.CreateGraphQLName(_ignoreOptions); + n.Value = value; + n.Comment = comment; + n.Location = GetLocation(start); + return n; } private ASTNode? ParseNamedDefinition() @@ -865,16 +726,11 @@ private GraphQLName ParseName() private GraphQLNamedType ParseNamedType() { int start = _currentToken.Start; - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLNamedType - { - Name = ParseName(), - } - : new GraphQLNamedTypeFull - { - Name = ParseName(), - Location = GetLocation(start) - }; + var named = NodeHelper.CreateGraphQLNamedType(_ignoreOptions); + named.Name = ParseName(); + named.Comment = null; //TODO: ???? + named.Location = GetLocation(start); + return named; } private GraphQLValue ParseNameValue(/*bool isConstant*/) @@ -902,54 +758,37 @@ private GraphQLValue Throw_From_ParseNameValue() private GraphQLValue ParseObject(bool isConstant) { - var comment = GetComment(); int start = _currentToken.Start; + var comment = GetComment(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLObjectValue - { - Fields = ParseObjectFields(isConstant), - } - : new GraphQLObjectValueFull - { - Comment = comment, - Fields = ParseObjectFields(isConstant), - Location = GetLocation(start) - }; + var val = NodeHelper.CreateGraphQLObjectValue(_ignoreOptions); + val.Fields = ParseObjectFields(isConstant); + val.Comment = comment; + val.Location = GetLocation(start); + return val; } private GraphQLValue ParseNullValue(Token token) { + var comment = GetComment(); Advance(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLScalarValue(ASTNodeKind.NullValue) - { - Value = token.Value, - } - : new GraphQLScalarValueFull(ASTNodeKind.NullValue) - { - Value = token.Value, - Location = GetLocation(token.Start) - }; + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.NullValue); + val.Value = token.Value; + val.Comment = comment; + val.Location = GetLocation(token.Start); + return val; } private GraphQLObjectField ParseObjectField(bool isConstant) { - var comment = GetComment(); int start = _currentToken.Start; - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLObjectField - { - Name = ParseName(), - Value = ExpectColonAndParseValueLiteral(isConstant), - } - : new GraphQLObjectFieldFull - { - Comment = comment, - Name = ParseName(), - Value = ExpectColonAndParseValueLiteral(isConstant), - Location = GetLocation(start) - }; + var comment = GetComment(); + var field = NodeHelper.CreateGraphQLObjectField(_ignoreOptions); + field.Name = ParseName(); + field.Value = ExpectColonAndParseValueLiteral(isConstant); + field.Comment = comment; + field.Location = GetLocation(start); + return field; } private List ParseObjectFields(bool isConstant) @@ -976,25 +815,15 @@ private GraphQLObjectTypeDefinition ParseObjectTypeDefinition() ExpectKeyword("type"); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLObjectTypeDefinition - { - Name = ParseName(), - Interfaces = ParseImplementsInterfaces(), - Directives = ParseDirectives(), - Fields = ParseFieldDefinitions(), - Description = description, - } - : new GraphQLObjectTypeDefinitionFull - { - Comment = comment, - Name = ParseName(), - Interfaces = ParseImplementsInterfaces(), - Directives = ParseDirectives(), - Fields = ParseFieldDefinitions(), - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLObjectTypeDefinition(_ignoreOptions); + def.Name = ParseName(); + def.Interfaces = ParseImplementsInterfaces(); + def.Directives = ParseDirectives(); + def.Fields = ParseFieldDefinitions(); + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private ASTNode ParseOperationDefinition() @@ -1009,43 +838,26 @@ private ASTNode ParseOperationDefinition() private ASTNode CreateOperationDefinition(int start) { var comment = GetComment(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLOperationDefinition - { - Operation = OperationType.Query, - SelectionSet = ParseSelectionSet(), - } - : new GraphQLOperationDefinitionFull - { - Comment = comment, - Operation = OperationType.Query, - SelectionSet = ParseSelectionSet(), - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLOperationDefinition(_ignoreOptions); + def.Operation = OperationType.Query; + def.SelectionSet = ParseSelectionSet(); + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private ASTNode CreateOperationDefinition(int start, OperationType operation, GraphQLName? name) { var comment = GetComment(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLOperationDefinition - { - Operation = operation, - Name = name, - VariableDefinitions = ParseVariableDefinitions(), - Directives = ParseDirectives(), - SelectionSet = ParseSelectionSet(), - } - : new GraphQLOperationDefinitionFull - { - Comment = comment, - Operation = operation, - Name = name, - VariableDefinitions = ParseVariableDefinitions(), - Directives = ParseDirectives(), - SelectionSet = ParseSelectionSet(), - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLOperationDefinition(_ignoreOptions); + def.Operation = operation; + def.Name = name; + def.VariableDefinitions = ParseVariableDefinitions(); + def.Directives = ParseDirectives(); + def.SelectionSet = ParseSelectionSet(); + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private OperationType ParseOperationType() @@ -1069,18 +881,12 @@ private GraphQLOperationTypeDefinition ParseOperationTypeDefinition() Expect(TokenKind.COLON); var type = ParseNamedType(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLOperationTypeDefinition - { - Operation = operation, - Type = type, - } - : new GraphQLOperationTypeDefinitionFull - { - Operation = operation, - Type = type, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLOperationTypeDefinition(_ignoreOptions); + def.Operation = operation; + def.Type = type; + def.Comment = null; //TODO: ???? + def.Location = GetLocation(start); + return def; } private GraphQLScalarTypeDefinition ParseScalarTypeDefinition() @@ -1097,21 +903,13 @@ private GraphQLScalarTypeDefinition ParseScalarTypeDefinition() var name = ParseName(); var directives = ParseDirectives(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLScalarTypeDefinition - { - Name = name, - Directives = directives, - Description = description, - } - : new GraphQLScalarTypeDefinitionFull - { - Comment = comment, - Name = name, - Directives = directives, - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLScalarTypeDefinition(_ignoreOptions); + def.Name = name; + def.Directives = directives; + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private GraphQLSchemaDefinition ParseSchemaDefinition() @@ -1128,21 +926,13 @@ private GraphQLSchemaDefinition ParseSchemaDefinition() var directives = ParseDirectives(); var operationTypes = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseOperationTypeDefinition(), TokenKind.BRACE_R); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLSchemaDefinition - { - Directives = directives, - OperationTypes = operationTypes, - Description = description, - } - : new GraphQLSchemaDefinitionFull - { - Comment = comment, - Directives = directives, - OperationTypes = operationTypes, - Description = description, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLSchemaDefinition(_ignoreOptions); + def.Directives = directives; + def.OperationTypes = operationTypes; + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private ASTNode ParseSelection() @@ -1155,48 +945,34 @@ private ASTNode ParseSelection() private GraphQLSelectionSet ParseSelectionSet() { int start = _currentToken.Start; - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLSelectionSet - { - Selections = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseSelection(), TokenKind.BRACE_R), - } - : new GraphQLSelectionSetFull - { - Selections = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseSelection(), TokenKind.BRACE_R), - Location = GetLocation(start) - }; + var selection = NodeHelper.CreateGraphQLSelectionSet(_ignoreOptions); + selection.Selections = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseSelection(), TokenKind.BRACE_R); + selection.Comment = null; //TODO: ??? + selection.Location = GetLocation(start); + return selection; } private GraphQLScalarValue ParseString(/*bool isConstant*/) { var token = _currentToken; + var comment = GetComment(); Advance(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLScalarValue(ASTNodeKind.StringValue) - { - Value = token.Value, - } - : new GraphQLScalarValueFull(ASTNodeKind.StringValue) - { - Value = token.Value, - Location = GetLocation(token.Start) - }; + + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.StringValue); + val.Value = token.Value; + val.Comment = comment; + val.Location = GetLocation(token.Start); + return val; } private GraphQLDescription ParseDescription() { var token = _currentToken; Advance(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLDescription() - { - Value = token.Value, - } - : new GraphQLDescription() - { - Value = token.Value, - Location = GetLocation(token.Start) - }; + var descr = NodeHelper.CreateGraphQLDescription(_ignoreOptions); + descr.Value = token.Value; + descr.Location = GetLocation(token.Start); + return descr; } private GraphQLType ParseType() @@ -1207,57 +983,41 @@ private GraphQLType ParseType() { type = ParseType(); Expect(TokenKind.BRACKET_R); - type = _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLListType - { - Type = type, - } - : new GraphQLListTypeFull - { - Type = type, - Location = GetLocation(start) - }; + var listType = NodeHelper.CreateGraphQLListType(_ignoreOptions); + listType.Type = type; + listType.Comment = null; //TODO: ??????????????? + listType.Location = GetLocation(start); + type = listType; } else { type = ParseNamedType(); } - return Skip(TokenKind.BANG) - ? (_ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLNonNullType - { - Type = type, - } - : new GraphQLNonNullTypeFull - { - Type = type, - Location = GetLocation(start) - }) - : type; + if (!Skip(TokenKind.BANG)) + return type; + + var nonNull = NodeHelper.CreateGraphQLNonNullType(_ignoreOptions); + nonNull.Type = type; + nonNull.Comment = null; /////TODO: ???? + nonNull.Location = GetLocation(start); + return nonNull; } private GraphQLTypeExtensionDefinition ParseTypeExtensionDefinition() { - var comment = GetComment(); int start = _currentToken.Start; + var comment = GetComment(); ExpectKeyword("extend"); var definition = ParseObjectTypeDefinition(); // Note that due to the spec extension definitions have no descriptions. - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLTypeExtensionDefinition - { - Name = definition.Name, - Definition = definition, - } - : new GraphQLTypeExtensionDefinitionFull - { - Comment = comment, - Name = definition.Name, - Definition = definition, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLTypeExtensionDefinition(_ignoreOptions); + def.Name = definition.Name; + def.Definition = definition; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private List ParseUnionMembers() @@ -1293,36 +1053,32 @@ private GraphQLUnionTypeDefinition ParseUnionTypeDefinition() Expect(TokenKind.EQUALS); var types = ParseUnionMembers(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLUnionTypeDefinition - { - Name = name, - Directives = directives, - Types = types, - Description = description, - } - : new GraphQLUnionTypeDefinitionFull - { - Comment = comment, - Name = name, - Directives = directives, - Types = types, - Description = description, - Location = GetLocation(start) - }; - } - - private GraphQLValue ParseValueLiteral(bool isConstant) => _currentToken.Kind switch - { - TokenKind.BRACKET_L => ParseList(isConstant), - TokenKind.BRACE_L => ParseObject(isConstant), - TokenKind.INT => ParseInt(/*isConstant*/), - TokenKind.FLOAT => ParseFloat(/*isConstant*/), - TokenKind.STRING => ParseString(/*isConstant*/), - TokenKind.NAME => ParseNameValue(/*isConstant*/), - TokenKind.DOLLAR when !isConstant => ParseVariable(), - _ => Throw_From_ParseValueLiteral() - }; + var def = NodeHelper.CreateGraphQLUnionTypeDefinition(_ignoreOptions); + def.Name = name; + def.Directives = directives; + def.Types = types; + def.Description = description; + def.Comment = comment; + def.Location = GetLocation(start); + return def; + } + + private GraphQLValue ParseValueLiteral(bool isConstant) + { + ParseComment(); + + return _currentToken.Kind switch + { + TokenKind.BRACKET_L => ParseList(isConstant), + TokenKind.BRACE_L => ParseObject(isConstant), + TokenKind.INT => ParseInt(/*isConstant*/), + TokenKind.FLOAT => ParseFloat(/*isConstant*/), + TokenKind.STRING => ParseString(/*isConstant*/), + TokenKind.NAME => ParseNameValue(/*isConstant*/), + TokenKind.DOLLAR when !isConstant => ParseVariable(), + _ => Throw_From_ParseValueLiteral() + }; + } private GraphQLValue Throw_From_ParseValueLiteral() { @@ -1332,40 +1088,28 @@ private GraphQLValue Throw_From_ParseValueLiteral() private GraphQLVariable ParseVariable() { int start = _currentToken.Start; + var comment = GetComment(); Expect(TokenKind.DOLLAR); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLVariable - { - Name = ParseName(), - } - : new GraphQLVariableFull - { - Name = ParseName(), - Location = GetLocation(start) - }; + var variable = NodeHelper.CreateGraphQLVariable(_ignoreOptions); + variable.Name = ParseName(); + variable.Comment = comment; + variable.Location = GetLocation(start); + return variable; } private GraphQLVariableDefinition ParseVariableDefinition() { - var comment = GetComment(); int start = _currentToken.Start; + var comment = GetComment(); - return _ignoreOptions.HasFlag(IgnoreOptions.Locations) - ? new GraphQLVariableDefinition - { - Variable = ParseVariable(), - Type = ExpectColonAndParseType(), - DefaultValue = Skip(TokenKind.EQUALS) ? ParseValueLiteral(true) : null, - } - : new GraphQLVariableDefinitionFull - { - Comment = comment, - Variable = ParseVariable(), - Type = ExpectColonAndParseType(), - DefaultValue = Skip(TokenKind.EQUALS) ? ParseValueLiteral(true) : null, - Location = GetLocation(start) - }; + var def = NodeHelper.CreateGraphQLVariableDefinition(_ignoreOptions); + def.Variable = ParseVariable(); + def.Type = ExpectColonAndParseType(); + def.DefaultValue = Skip(TokenKind.EQUALS) ? ParseValueLiteral(true) : null; + def.Comment = comment; + def.Location = GetLocation(start); + return def; } private List? ParseVariableDefinitions() From f44ea9c4566ccf7d584bb932c706b78362f8d573 Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Wed, 10 Nov 2021 00:39:05 +0300 Subject: [PATCH 3/4] comments rework and documentation --- .../GraphQL-Parser.approved.txt | 30 +- .../Files/CommentsOnDirective.graphql | 3 + .../Files/CommentsOnNamedType.graphql | 33 ++ .../Files/CommentsOnRootOperationType.graphql | 4 + .../Files/CommentsOnSelectionSet.graphql | 5 + .../Files/CommentsOnType.graphql | 14 + .../Files/CommentsOnVariables.graphql | 4 +- .../GraphQLAstVisitorTests.cs | 20 +- src/GraphQLParser.Tests/Issue82.cs | 2 +- src/GraphQLParser.Tests/ParserTests.cs | 111 +++++- src/GraphQLParser/AST/ASTNodeKind.cs | 60 ++++ src/GraphQLParser/AST/GraphQLDocument.cs | 32 +- ...aphQLFieldSelection.cs => GraphQLField.cs} | 8 +- ... => GraphQLRootOperationTypeDefinition.cs} | 8 +- .../AST/GraphQLSchemaDefinition.cs | 2 +- src/GraphQLParser/GraphQLAstVisitor.cs | 16 +- src/GraphQLParser/Location.cs | 2 +- src/GraphQLParser/NodeHelper.cs | 28 +- src/GraphQLParser/Parser.cs | 3 +- src/GraphQLParser/ParserContext.Parse.cs | 340 ++++++++++-------- src/GraphQLParser/ParserContext.cs | 45 +-- src/GraphQLParser/ROM.cs | 6 +- 22 files changed, 497 insertions(+), 279 deletions(-) create mode 100644 src/GraphQLParser.Tests/Files/CommentsOnDirective.graphql create mode 100644 src/GraphQLParser.Tests/Files/CommentsOnNamedType.graphql create mode 100644 src/GraphQLParser.Tests/Files/CommentsOnRootOperationType.graphql create mode 100644 src/GraphQLParser.Tests/Files/CommentsOnSelectionSet.graphql create mode 100644 src/GraphQLParser.Tests/Files/CommentsOnType.graphql rename src/GraphQLParser/AST/{GraphQLFieldSelection.cs => GraphQLField.cs} (79%) rename src/GraphQLParser/AST/{GraphQLOperationTypeDefinition.cs => GraphQLRootOperationTypeDefinition.cs} (72%) diff --git a/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt b/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt index 132fd9b9..05d9e7b1 100644 --- a/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt +++ b/src/GraphQLParser.ApiTests/GraphQL-Parser.approved.txt @@ -105,17 +105,9 @@ namespace GraphQLParser.AST public System.Collections.Generic.List? Directives { get; set; } public override GraphQLParser.AST.ASTNodeKind Kind { get; } } - public class GraphQLFieldDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode - { - public GraphQLFieldDefinition() { } - public System.Collections.Generic.List? Arguments { get; set; } - public System.Collections.Generic.List? Directives { get; set; } - public override GraphQLParser.AST.ASTNodeKind Kind { get; } - public GraphQLParser.AST.GraphQLType? Type { get; set; } - } - public class GraphQLFieldSelection : GraphQLParser.AST.ASTNode, GraphQLParser.AST.IHasDirectivesNode, GraphQLParser.AST.INamedNode + public class GraphQLField : GraphQLParser.AST.ASTNode, GraphQLParser.AST.IHasDirectivesNode, GraphQLParser.AST.INamedNode { - public GraphQLFieldSelection() { } + public GraphQLField() { } public GraphQLParser.AST.GraphQLName? Alias { get; set; } public System.Collections.Generic.List? Arguments { get; set; } public System.Collections.Generic.List? Directives { get; set; } @@ -123,6 +115,14 @@ namespace GraphQLParser.AST public GraphQLParser.AST.GraphQLName? Name { get; set; } public GraphQLParser.AST.GraphQLSelectionSet? SelectionSet { get; set; } } + public class GraphQLFieldDefinition : GraphQLParser.AST.GraphQLTypeDefinition, GraphQLParser.AST.IHasDirectivesNode + { + public GraphQLFieldDefinition() { } + public System.Collections.Generic.List? Arguments { get; set; } + public System.Collections.Generic.List? Directives { get; set; } + public override GraphQLParser.AST.ASTNodeKind Kind { get; } + public GraphQLParser.AST.GraphQLType? Type { get; set; } + } public class GraphQLFragmentDefinition : GraphQLParser.AST.GraphQLInlineFragment, GraphQLParser.AST.INamedNode { public GraphQLFragmentDefinition() { } @@ -244,9 +244,9 @@ namespace GraphQLParser.AST public GraphQLParser.AST.GraphQLSelectionSet? SelectionSet { get; set; } public System.Collections.Generic.List? VariableDefinitions { get; set; } } - public class GraphQLOperationTypeDefinition : GraphQLParser.AST.ASTNode + public class GraphQLRootOperationTypeDefinition : GraphQLParser.AST.ASTNode { - public GraphQLOperationTypeDefinition() { } + public GraphQLRootOperationTypeDefinition() { } public override GraphQLParser.AST.ASTNodeKind Kind { get; } public GraphQLParser.AST.OperationType Operation { get; set; } public GraphQLParser.AST.GraphQLNamedType? Type { get; set; } @@ -270,7 +270,7 @@ namespace GraphQLParser.AST public GraphQLParser.AST.GraphQLDescription? Description { get; set; } public System.Collections.Generic.List? Directives { get; set; } public override GraphQLParser.AST.ASTNodeKind Kind { get; } - public System.Collections.Generic.List? OperationTypes { get; set; } + public System.Collections.Generic.List? OperationTypes { get; set; } } public class GraphQLSelectionSet : GraphQLParser.AST.ASTNode { @@ -361,7 +361,7 @@ namespace GraphQLParser public virtual GraphQLParser.AST.GraphQLDirective BeginVisitDirective(GraphQLParser.AST.GraphQLDirective directive) { } public virtual System.Collections.Generic.IEnumerable BeginVisitDirectives(System.Collections.Generic.IEnumerable directives) { } public virtual GraphQLParser.AST.GraphQLScalarValue BeginVisitEnumValue(GraphQLParser.AST.GraphQLScalarValue value) { } - public virtual GraphQLParser.AST.GraphQLFieldSelection BeginVisitFieldSelection(GraphQLParser.AST.GraphQLFieldSelection selection) { } + public virtual GraphQLParser.AST.GraphQLField BeginVisitField(GraphQLParser.AST.GraphQLField selection) { } public virtual GraphQLParser.AST.GraphQLScalarValue BeginVisitFloatValue(GraphQLParser.AST.GraphQLScalarValue value) { } public virtual GraphQLParser.AST.GraphQLFragmentDefinition BeginVisitFragmentDefinition(GraphQLParser.AST.GraphQLFragmentDefinition node) { } public virtual GraphQLParser.AST.GraphQLFragmentSpread BeginVisitFragmentSpread(GraphQLParser.AST.GraphQLFragmentSpread fragmentSpread) { } @@ -379,7 +379,7 @@ namespace GraphQLParser public virtual GraphQLParser.AST.GraphQLVariableDefinition BeginVisitVariableDefinition(GraphQLParser.AST.GraphQLVariableDefinition node) { } public virtual System.Collections.Generic.IEnumerable BeginVisitVariableDefinitions(System.Collections.Generic.IEnumerable variableDefinitions) { } public virtual GraphQLParser.AST.GraphQLArgument EndVisitArgument(GraphQLParser.AST.GraphQLArgument argument) { } - public virtual GraphQLParser.AST.GraphQLFieldSelection EndVisitFieldSelection(GraphQLParser.AST.GraphQLFieldSelection selection) { } + public virtual GraphQLParser.AST.GraphQLField EndVisitField(GraphQLParser.AST.GraphQLField selection) { } public virtual GraphQLParser.AST.GraphQLListValue EndVisitListValue(GraphQLParser.AST.GraphQLListValue node) { } public virtual GraphQLParser.AST.GraphQLObjectValue EndVisitObjectValue(GraphQLParser.AST.GraphQLObjectValue node) { } public virtual GraphQLParser.AST.GraphQLOperationDefinition EndVisitOperationDefinition(GraphQLParser.AST.GraphQLOperationDefinition definition) { } diff --git a/src/GraphQLParser.Tests/Files/CommentsOnDirective.graphql b/src/GraphQLParser.Tests/Files/CommentsOnDirective.graphql new file mode 100644 index 00000000..6c37e6f8 --- /dev/null +++ b/src/GraphQLParser.Tests/Files/CommentsOnDirective.graphql @@ -0,0 +1,3 @@ +scalar Json +#comment for directive +@external diff --git a/src/GraphQLParser.Tests/Files/CommentsOnNamedType.graphql b/src/GraphQLParser.Tests/Files/CommentsOnNamedType.graphql new file mode 100644 index 00000000..4fc74ca1 --- /dev/null +++ b/src/GraphQLParser.Tests/Files/CommentsOnNamedType.graphql @@ -0,0 +1,33 @@ +# aaa + +query _ { + person { + ... on + #comment for named type from TypeCondition + human { + name + } + } +} + +type A implements + #comment for named type from ImplementsInterfaces + B { + name : String +} + +schema { + query: + #comment for named type from RootOperationTypeDefinition + Query +} + +type Query { + field: + #comment for named type from Type + String +} + +union U = A | +#comment for named type from UnionMemberTypes +B diff --git a/src/GraphQLParser.Tests/Files/CommentsOnRootOperationType.graphql b/src/GraphQLParser.Tests/Files/CommentsOnRootOperationType.graphql new file mode 100644 index 00000000..08fe168f --- /dev/null +++ b/src/GraphQLParser.Tests/Files/CommentsOnRootOperationType.graphql @@ -0,0 +1,4 @@ +schema { + #comment for root operation type + query: Query +} diff --git a/src/GraphQLParser.Tests/Files/CommentsOnSelectionSet.graphql b/src/GraphQLParser.Tests/Files/CommentsOnSelectionSet.graphql new file mode 100644 index 00000000..ca21df55 --- /dev/null +++ b/src/GraphQLParser.Tests/Files/CommentsOnSelectionSet.graphql @@ -0,0 +1,5 @@ +query +#comment on selection set +{ + name +} diff --git a/src/GraphQLParser.Tests/Files/CommentsOnType.graphql b/src/GraphQLParser.Tests/Files/CommentsOnType.graphql new file mode 100644 index 00000000..9322f0c6 --- /dev/null +++ b/src/GraphQLParser.Tests/Files/CommentsOnType.graphql @@ -0,0 +1,14 @@ +type Person { + name: + #comment for named type + String + age: + #comment for nonnull type + Int! + friends: + #comment for list type + [ + #comment for item type + Person + ] +} diff --git a/src/GraphQLParser.Tests/Files/CommentsOnVariables.graphql b/src/GraphQLParser.Tests/Files/CommentsOnVariables.graphql index 628b68b0..7f44d373 100644 --- a/src/GraphQLParser.Tests/Files/CommentsOnVariables.graphql +++ b/src/GraphQLParser.Tests/Files/CommentsOnVariables.graphql @@ -1,6 +1,8 @@ query _( #comment1 - $id: ID, + $id: + #comment on variable type + ID, $id2: String!, #comment3 $id3: String) { diff --git a/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs b/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs index 06fc971a..f14569f3 100644 --- a/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs +++ b/src/GraphQLParser.Tests/GraphQLAstVisitorTests.cs @@ -15,7 +15,7 @@ public class GraphQLAstVisitorTests private readonly List _visitedDefinitions; private readonly List _visitedDirectives; private readonly List _visitedEnumValues; - private readonly List _visitedFieldSelections; + private readonly List _visitedFields; private readonly List _visitedFloatValues; private readonly List _visitedFragmentDefinitions; private readonly List _visitedFragmentSpreads; @@ -35,7 +35,7 @@ public GraphQLAstVisitorTests() _visitedDefinitions = MockVisitMethod((visitor) => visitor.BeginVisitOperationDefinition(null)); _visitedSelectionSets = MockVisitMethod((visitor) => visitor.BeginVisitSelectionSet(null)); - _visitedFieldSelections = MockVisitMethod((visitor) => visitor.BeginVisitFieldSelection(null)); + _visitedFields = MockVisitMethod((visitor) => visitor.BeginVisitField(null)); _visitedNames = MockVisitMethod((visitor) => visitor.BeginVisitName(null)); _visitedArguments = MockVisitMethod((visitor) => visitor.BeginVisitArgument(null)); _visitedAliases = MockVisitMethod((visitor) => visitor.BeginVisitAlias(null)); @@ -205,7 +205,7 @@ public void Visit_InlineFragmentWithOneField_VisitsOneField(IgnoreOptions option using var d = "{ ... @include(if : $stuff) { field } }".Parse(new ParserOptions { Ignore = options }); _visitor.Visit(d); - _visitedFieldSelections.ShouldHaveSingleItem(); + _visitedFields.ShouldHaveSingleItem(); } [Theory] @@ -356,12 +356,12 @@ public void Visit_TwoDefinitions_CallsVisitDefinitionTwice(IgnoreOptions options [InlineData(IgnoreOptions.Comments)] [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] - public void Visit_TwoFieldSelections_VisitsFieldSelectionTwice(IgnoreOptions options) + public void Visit_TwoFields_VisitsFieldTwice(IgnoreOptions options) { using var d = "{ a, b }".Parse(new ParserOptions { Ignore = options }); _visitor.Visit(d); - _visitedFieldSelections.Count.ShouldBe(2); + _visitedFields.Count.ShouldBe(2); } [Theory] @@ -369,7 +369,7 @@ public void Visit_TwoFieldSelections_VisitsFieldSelectionTwice(IgnoreOptions opt [InlineData(IgnoreOptions.Comments)] [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] - public void Visit_TwoFieldSelections_VisitsTwoFieldNames(IgnoreOptions options) + public void Visit_TwoFields_VisitsTwoFieldNames(IgnoreOptions options) { using var d = "{ a, b }".Parse(new ParserOptions { Ignore = options }); _visitor.Visit(d); @@ -382,7 +382,7 @@ public void Visit_TwoFieldSelections_VisitsTwoFieldNames(IgnoreOptions options) [InlineData(IgnoreOptions.Comments)] [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] - public void Visit_TwoFieldSelections_VisitsTwoFieldNamesAndDefinitionName(IgnoreOptions options) + public void Visit_TwoFields_VisitsTwoFieldNamesAndDefinitionName(IgnoreOptions options) { using var d = "query foo { a, b }".Parse(new ParserOptions { Ignore = options }); _visitor.Visit(d); @@ -395,12 +395,12 @@ public void Visit_TwoFieldSelections_VisitsTwoFieldNamesAndDefinitionName(Ignore [InlineData(IgnoreOptions.Comments)] [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] - public void Visit_TwoFieldSelectionsWithOneNested_VisitsFiveFieldSelections(IgnoreOptions options) + public void Visit_TwoFieldsWithOneNested_VisitsFiveFields(IgnoreOptions options) { using var d = "{a, nested { x, y }, b}".Parse(new ParserOptions { Ignore = options }); _visitor.Visit(d); - _visitedFieldSelections.Count.ShouldBe(5); + _visitedFields.Count.ShouldBe(5); } [Theory] @@ -408,7 +408,7 @@ public void Visit_TwoFieldSelectionsWithOneNested_VisitsFiveFieldSelections(Igno [InlineData(IgnoreOptions.Comments)] [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] - public void Visit_TwoFieldSelectionsWithOneNested_VisitsFiveNames(IgnoreOptions options) + public void Visit_TwoFieldsWithOneNested_VisitsFiveNames(IgnoreOptions options) { using var d = "{a, nested { x, y }, b}".Parse(new ParserOptions { Ignore = options }); _visitor.Visit(d); diff --git a/src/GraphQLParser.Tests/Issue82.cs b/src/GraphQLParser.Tests/Issue82.cs index c1c34faf..499d3a33 100644 --- a/src/GraphQLParser.Tests/Issue82.cs +++ b/src/GraphQLParser.Tests/Issue82.cs @@ -27,7 +27,7 @@ public void Parse_Named_And_Literal_Variables(IgnoreOptions options) def.VariableDefinitions[0].Type.ShouldBeAssignableTo().Name.Value.ShouldBe("String"); def.VariableDefinitions[0].Variable.Name.Value.ShouldBe("username"); - var selection = def.SelectionSet.Selections[0].ShouldBeAssignableTo(); + var selection = def.SelectionSet.Selections[0].ShouldBeAssignableTo(); selection.Arguments.Count.ShouldBe(2); selection.Arguments[0].Value.ShouldBeAssignableTo().Name.Value.ShouldBe("username"); selection.Arguments[1].Value.ShouldBeAssignableTo().Value.ShouldBe("Pete"); diff --git a/src/GraphQLParser.Tests/ParserTests.cs b/src/GraphQLParser.Tests/ParserTests.cs index 4ee1936f..ae48d9fc 100644 --- a/src/GraphQLParser.Tests/ParserTests.cs +++ b/src/GraphQLParser.Tests/ParserTests.cs @@ -27,17 +27,17 @@ public void Extra_Comments_Should_Read_Correctly(IgnoreOptions options) var def = document.Definitions.First() as GraphQLOperationDefinition; def.SelectionSet.Selections.Count.ShouldBe(2); // person - var field = def.SelectionSet.Selections.First() as GraphQLFieldSelection; + var field = def.SelectionSet.Selections.First() as GraphQLField; field.SelectionSet.Selections.Count.ShouldBe(1); // name - var subField = field.SelectionSet.Selections.First() as GraphQLFieldSelection; + var subField = field.SelectionSet.Selections.First() as GraphQLField; subField.Comment.ShouldBeNull(); // test - field = def.SelectionSet.Selections.Last() as GraphQLFieldSelection; + field = def.SelectionSet.Selections.Last() as GraphQLField; field.SelectionSet.Selections.Count.ShouldBe(1); field.Comment.ShouldNotBeNull().Text.ShouldBe("comment2"); // alt - subField = field.SelectionSet.Selections.First() as GraphQLFieldSelection; + subField = field.SelectionSet.Selections.First() as GraphQLField; subField.Comment.ShouldBeNull(); // extra document comments document.UnattachedComments.Count.ShouldBe(3); @@ -66,7 +66,7 @@ public void Comments_Can_Be_Ignored(IgnoreOptions options) var def = document.Definitions.First() as GraphQLOperationDefinition; def.SelectionSet.Selections.Count.ShouldBe(1); def.Comment.ShouldBeNull(); - var field = def.SelectionSet.Selections.First() as GraphQLFieldSelection; + var field = def.SelectionSet.Selections.First() as GraphQLField; field.Comment.ShouldBeNull(); } @@ -83,7 +83,7 @@ public void Comments_on_FragmentSpread_Should_Read_Correctly(IgnoreOptions optio document.Definitions.Count.ShouldBe(2); var def = document.Definitions.First() as GraphQLOperationDefinition; def.SelectionSet.Selections.Count.ShouldBe(1); - var field = def.SelectionSet.Selections.First() as GraphQLFieldSelection; + var field = def.SelectionSet.Selections.First() as GraphQLField; field.SelectionSet.Selections.Count.ShouldBe(1); var fragment = field.SelectionSet.Selections.First() as GraphQLFragmentSpread; fragment.Comment.ShouldNotBeNull().Text.ShouldBe("comment"); @@ -102,7 +102,7 @@ public void Comments_on_Values_Should_Read_Correctly(IgnoreOptions options) document.Definitions.Count.ShouldBe(1); var def = document.Definitions.First() as GraphQLOperationDefinition; def.SelectionSet.Selections.Count.ShouldBe(1); - var field = def.SelectionSet.Selections.First() as GraphQLFieldSelection; + var field = def.SelectionSet.Selections.First() as GraphQLField; field.SelectionSet.Selections.Count.ShouldBe(1); field.Arguments.Count.ShouldBe(9); @@ -147,12 +147,105 @@ public void Comments_on_FragmentInline_Should_Read_Correctly(IgnoreOptions optio document.Definitions.Count.ShouldBe(1); var def = document.Definitions.First() as GraphQLOperationDefinition; def.SelectionSet.Selections.Count.ShouldBe(1); - var field = def.SelectionSet.Selections.First() as GraphQLFieldSelection; + var field = def.SelectionSet.Selections.First() as GraphQLField; field.SelectionSet.Selections.Count.ShouldBe(1); var fragment = field.SelectionSet.Selections.First() as GraphQLInlineFragment; fragment.Comment.ShouldNotBeNull().Text.ShouldBe("comment"); } + [Theory] + [InlineData(IgnoreOptions.None)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_NamedTypes_Should_Read_Correctly(IgnoreOptions options) + { + string query = "CommentsOnNamedType".ReadGraphQLFile(); + + using var document = query.Parse(new ParserOptions { Ignore = options }); + document.Definitions.Count.ShouldBe(5); + + var def1 = document.Definitions[0] as GraphQLOperationDefinition; + var field = def1.SelectionSet.Selections[0] as GraphQLField; + var frag = field.SelectionSet.Selections[0] as GraphQLInlineFragment; + frag.TypeCondition.Comment.Text.ShouldBe("comment for named type from TypeCondition"); + + var def2 = document.Definitions[1] as GraphQLObjectTypeDefinition; + def2.Interfaces[0].Comment.Text.ShouldBe("comment for named type from ImplementsInterfaces"); + + var def3 = document.Definitions[2] as GraphQLSchemaDefinition; + def3.OperationTypes[0].Type.Comment.Text.ShouldBe("comment for named type from RootOperationTypeDefinition"); + + var def4 = document.Definitions[3] as GraphQLObjectTypeDefinition; + def4.Fields[0].Type.Comment.Text.ShouldBe("comment for named type from Type"); + + var def5 = document.Definitions[4] as GraphQLUnionTypeDefinition; + def5.Types[1].Comment.Text.ShouldBe("comment for named type from UnionMemberTypes"); + } + + [Theory] + [InlineData(IgnoreOptions.None)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_SelectionSet_Should_Read_Correctly(IgnoreOptions options) + { + string query = "CommentsOnSelectionSet".ReadGraphQLFile(); + + using var document = query.Parse(new ParserOptions { Ignore = options }); + document.Definitions.Count.ShouldBe(1); + var def = document.Definitions[0] as GraphQLOperationDefinition; + def.SelectionSet.Comment.Text.ShouldBe("comment on selection set"); + } + + [Theory] + [InlineData(IgnoreOptions.None)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_RootOperationType_Should_Read_Correctly(IgnoreOptions options) + { + string query = "CommentsOnRootOperationType".ReadGraphQLFile(); + + using var document = query.Parse(new ParserOptions { Ignore = options }); + document.Definitions.Count.ShouldBe(1); + var def = document.Definitions[0] as GraphQLSchemaDefinition; + def.OperationTypes[0].Comment.Text.ShouldBe("comment for root operation type"); + } + + [Theory] + [InlineData(IgnoreOptions.None)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_Directive_Should_Read_Correctly(IgnoreOptions options) + { + string query = "CommentsOnDirective".ReadGraphQLFile(); + + using var document = query.Parse(new ParserOptions { Ignore = options }); + document.Definitions.Count.ShouldBe(1); + var def = document.Definitions[0] as GraphQLScalarTypeDefinition; + def.Directives[0].Comment.Text.ShouldBe("comment for directive"); + } + + [Theory] + [InlineData(IgnoreOptions.None)] + //[InlineData(IgnoreOptions.Comments)] + [InlineData(IgnoreOptions.Locations)] + //[InlineData(IgnoreOptions.All)] + public void Comments_on_Type_Should_Read_Correctly(IgnoreOptions options) + { + string query = "CommentsOnType".ReadGraphQLFile(); + + using var document = query.Parse(new ParserOptions { Ignore = options }); + document.Definitions.Count.ShouldBe(1); + var def = document.Definitions[0] as GraphQLObjectTypeDefinition; + def.Fields[0].Type.Comment.Text.ShouldBe("comment for named type"); + def.Fields[1].Type.Comment.Text.ShouldBe("comment for nonnull type"); + def.Fields[2].Type.Comment.Text.ShouldBe("comment for list type"); + (def.Fields[2].Type as GraphQLListType).Type.Comment.Text.ShouldBe("comment for item type"); + } + [Theory] [InlineData(IgnoreOptions.None)] //[InlineData(IgnoreOptions.Comments)] @@ -317,7 +410,7 @@ public void Parse_FieldInput_ReturnsDocumentNode(IgnoreOptions options) [InlineData(IgnoreOptions.Comments)] [InlineData(IgnoreOptions.Locations)] [InlineData(IgnoreOptions.All)] - public void Parse_FieldInput_SelectionSetContainsSingleFieldSelection(IgnoreOptions options) + public void Parse_FieldInput_SelectionSetContainsSingleField(IgnoreOptions options) { using var document = ParseGraphQLFieldSource(options); diff --git a/src/GraphQLParser/AST/ASTNodeKind.cs b/src/GraphQLParser/AST/ASTNodeKind.cs index 8995a02d..9b611bbd 100644 --- a/src/GraphQLParser/AST/ASTNodeKind.cs +++ b/src/GraphQLParser/AST/ASTNodeKind.cs @@ -15,8 +15,24 @@ public enum ASTNodeKind OperationDefinition, VariableDefinition, Variable, + + /// + /// An operation selects the set of information it needs, and will + /// receive exactly that information and nothing more, avoiding + /// over-fetching and under-fetching data. + /// SelectionSet, + + /// + /// A selection set is primarily composed of fields. A field describes + /// one discrete piece of information available to request within a selection set. + /// Field, + + /// + /// Fields are conceptually functions which return values, and occasionally + /// accept arguments which alter their behavior. + /// Argument, FragmentSpread, InlineFragment, @@ -42,9 +58,33 @@ public enum ASTNodeKind /// Boolean value. The two keywords true and false represent the two boolean values. /// BooleanValue, + + /// + /// Enum values are represented as unquoted names (ex. MOBILE_WEB). It is recommended + /// that Enum values be "all caps". Enum values are only used in contexts where the + /// precise enumeration type is known. Therefore it’s not necessary to supply an + /// enumeration type name in the literal. + /// EnumValue, + + /// + /// Lists are ordered sequences of values wrapped in square-brackets [ ]. + /// The values of a List literal may be any value literal or variable (ex. [1, 2, 3]). + /// Commas are optional throughout GraphQL so trailing commas are allowed and repeated + /// commas do not represent missing values. + /// ListValue, + + /// + /// Input object literal values are unordered lists of keyed input values wrapped + /// in curly-braces { }. The values of an object literal may be any input value + /// literal or variable (ex. { name: "Hello world", score: 1.0 }). + /// ObjectValue, + + /// + /// A keyed input value within . + /// ObjectField, /// @@ -53,8 +93,28 @@ public enum ASTNodeKind /// additional information for types, fields, fragments, operations, etc. /// Directive, + + /// + /// The fundamental unit of any GraphQL Schema is the type. There are six kinds of named + /// type definitions in GraphQL, and two wrapping types. In other words all non-wrapping + /// types are referred to as "named types". + /// NamedType, + + /// + /// Wrapping type. A GraphQL schema may describe that a field represents a list of + /// another type; the List type is provided for this reason, and wraps another type. + /// A wrapping type has an underlying named type, found by continually unwrapping + /// the type until a named type is found. + /// ListType, + + /// + /// Wrapping type. The Non-Null type wraps another type, and denotes that the resulting + /// value will never be null (and that a field error cannot result in a null value). + /// A wrapping type has an underlying named type, found by continually unwrapping + /// the type until a named type is found. + /// NonNullType, /// diff --git a/src/GraphQLParser/AST/GraphQLDocument.cs b/src/GraphQLParser/AST/GraphQLDocument.cs index c9eaea19..62d0c989 100644 --- a/src/GraphQLParser/AST/GraphQLDocument.cs +++ b/src/GraphQLParser/AST/GraphQLDocument.cs @@ -45,6 +45,7 @@ protected virtual void Dispose(bool disposing) public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } } @@ -58,35 +59,4 @@ public override GraphQLLocation Location set => _location = value; } } - - //TODO: GraphQLDocument has no comments - - //internal sealed class GraphQLDocumentWithComment : GraphQLDocument - //{ - // private GraphQLComment? _comment; - - // public override GraphQLComment? Comment - // { - // get => _comment; - // set => _comment = value; - // } - //} - - //internal sealed class GraphQLDocumentFull : GraphQLDocument - //{ - // private GraphQLLocation _location; - // private GraphQLComment? _comment; - - // public override GraphQLLocation Location - // { - // get => _location; - // set => _location = value; - // } - - // public override GraphQLComment? Comment - // { - // get => _comment; - // set => _comment = value; - // } - //} } diff --git a/src/GraphQLParser/AST/GraphQLFieldSelection.cs b/src/GraphQLParser/AST/GraphQLField.cs similarity index 79% rename from src/GraphQLParser/AST/GraphQLFieldSelection.cs rename to src/GraphQLParser/AST/GraphQLField.cs index 9641a2f2..993e8c63 100644 --- a/src/GraphQLParser/AST/GraphQLFieldSelection.cs +++ b/src/GraphQLParser/AST/GraphQLField.cs @@ -2,7 +2,7 @@ namespace GraphQLParser.AST { - public class GraphQLFieldSelection : ASTNode, IHasDirectivesNode, INamedNode + public class GraphQLField : ASTNode, IHasDirectivesNode, INamedNode { public GraphQLName? Alias { get; set; } @@ -20,7 +20,7 @@ public class GraphQLFieldSelection : ASTNode, IHasDirectivesNode, INamedNode public GraphQLSelectionSet? SelectionSet { get; set; } } - internal sealed class GraphQLFieldSelectionWithLocation : GraphQLFieldSelection + internal sealed class GraphQLFieldWithLocation : GraphQLField { private GraphQLLocation _location; @@ -31,7 +31,7 @@ public override GraphQLLocation Location } } - internal sealed class GraphQLFieldSelectionWithComment : GraphQLFieldSelection + internal sealed class GraphQLFieldWithComment : GraphQLField { private GraphQLComment? _comment; @@ -42,7 +42,7 @@ public override GraphQLComment? Comment } } - internal sealed class GraphQLFieldSelectionFull : GraphQLFieldSelection + internal sealed class GraphQLFieldFull : GraphQLField { private GraphQLLocation _location; private GraphQLComment? _comment; diff --git a/src/GraphQLParser/AST/GraphQLOperationTypeDefinition.cs b/src/GraphQLParser/AST/GraphQLRootOperationTypeDefinition.cs similarity index 72% rename from src/GraphQLParser/AST/GraphQLOperationTypeDefinition.cs rename to src/GraphQLParser/AST/GraphQLRootOperationTypeDefinition.cs index f856f5a3..037b49c0 100644 --- a/src/GraphQLParser/AST/GraphQLOperationTypeDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLRootOperationTypeDefinition.cs @@ -1,6 +1,6 @@ namespace GraphQLParser.AST { - public class GraphQLOperationTypeDefinition : ASTNode + public class GraphQLRootOperationTypeDefinition : ASTNode { /// public override ASTNodeKind Kind => ASTNodeKind.OperationTypeDefinition; @@ -10,7 +10,7 @@ public class GraphQLOperationTypeDefinition : ASTNode public GraphQLNamedType? Type { get; set; } } - internal sealed class GraphQLOperationTypeDefinitionWithLocation : GraphQLOperationTypeDefinition + internal sealed class GraphQLRootOperationTypeDefinitionWithLocation : GraphQLRootOperationTypeDefinition { private GraphQLLocation _location; @@ -21,7 +21,7 @@ public override GraphQLLocation Location } } - internal sealed class GraphQLOperationTypeDefinitionWithComment : GraphQLOperationTypeDefinition + internal sealed class GraphQLRootOperationTypeDefinitionWithComment : GraphQLRootOperationTypeDefinition { private GraphQLComment? _comment; @@ -32,7 +32,7 @@ public override GraphQLComment? Comment } } - internal sealed class GraphQLOperationTypeDefinitionFull : GraphQLOperationTypeDefinition + internal sealed class GraphQLRootOperationTypeDefinitionFull : GraphQLRootOperationTypeDefinition { private GraphQLLocation _location; private GraphQLComment? _comment; diff --git a/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs b/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs index e68d2b2a..a2cc04c5 100644 --- a/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs +++ b/src/GraphQLParser/AST/GraphQLSchemaDefinition.cs @@ -13,7 +13,7 @@ public class GraphQLSchemaDefinition : ASTNode, IHasDirectivesNode, IHasDescript /// public override ASTNodeKind Kind => ASTNodeKind.SchemaDefinition; - public List? OperationTypes { get; set; } + public List? OperationTypes { get; set; } } internal sealed class GraphQLSchemaDefinitionWithLocation : GraphQLSchemaDefinition diff --git a/src/GraphQLParser/GraphQLAstVisitor.cs b/src/GraphQLParser/GraphQLAstVisitor.cs index dc9e0bc6..089709d3 100644 --- a/src/GraphQLParser/GraphQLAstVisitor.cs +++ b/src/GraphQLParser/GraphQLAstVisitor.cs @@ -4,7 +4,7 @@ namespace GraphQLParser { - public class GraphQLAstVisitor //TODO: not used + public class GraphQLAstVisitor // TODO: not used { protected IDictionary Fragments { get; private set; } @@ -57,7 +57,7 @@ public virtual IEnumerable BeginVisitDirectives(IEnumerable value; - public virtual GraphQLFieldSelection BeginVisitFieldSelection(GraphQLFieldSelection selection) + public virtual GraphQLField BeginVisitField(GraphQLField selection) { BeginVisitNode(selection.Name); @@ -73,7 +73,7 @@ public virtual GraphQLFieldSelection BeginVisitFieldSelection(GraphQLFieldSelect if (selection.Directives != null) BeginVisitDirectives(selection.Directives); - return EndVisitFieldSelection(selection); + return EndVisitField(selection); } public virtual GraphQLScalarValue BeginVisitFloatValue(GraphQLScalarValue value) => value; @@ -119,7 +119,7 @@ public virtual GraphQLInlineFragment BeginVisitInlineFragment(GraphQLInlineFragm { ASTNodeKind.OperationDefinition => BeginVisitOperationDefinition((GraphQLOperationDefinition)node), ASTNodeKind.SelectionSet => BeginVisitSelectionSet((GraphQLSelectionSet)node), - ASTNodeKind.Field => BeginVisitNonIntrospectionFieldSelection((GraphQLFieldSelection)node), + ASTNodeKind.Field => BeginVisitNonIntrospectionField((GraphQLField)node), ASTNodeKind.Name => BeginVisitName((GraphQLName)node), ASTNodeKind.Argument => BeginVisitArgument((GraphQLArgument)node), ASTNodeKind.FragmentSpread => BeginVisitFragmentSpread((GraphQLFragmentSpread)node), @@ -193,7 +193,7 @@ public virtual IEnumerable BeginVisitVariableDefiniti public virtual GraphQLArgument EndVisitArgument(GraphQLArgument argument) => argument; - public virtual GraphQLFieldSelection EndVisitFieldSelection(GraphQLFieldSelection selection) => selection; + public virtual GraphQLField EndVisitField(GraphQLField selection) => selection; public virtual GraphQLVariable EndVisitVariable(GraphQLVariable variable) => variable; @@ -206,7 +206,7 @@ public virtual void Visit(GraphQLDocument ast) if (definition.Kind == ASTNodeKind.FragmentDefinition) { var fragment = (GraphQLFragmentDefinition)definition; - string? name = fragment.Name?.Value.ToString(); //TODO: heap allocation + string? name = fragment.Name?.Value.ToString(); // TODO: heap allocation if (name == null) throw new InvalidOperationException("Fragment name cannot be null"); @@ -256,9 +256,9 @@ private ASTNode BeginVisitListValue(GraphQLListValue node) return EndVisitListValue(node); } - private ASTNode BeginVisitNonIntrospectionFieldSelection(GraphQLFieldSelection selection) + private ASTNode BeginVisitNonIntrospectionField(GraphQLField selection) { - return BeginVisitFieldSelection(selection); + return BeginVisitField(selection); } } } diff --git a/src/GraphQLParser/Location.cs b/src/GraphQLParser/Location.cs index c504553d..0a4b6e28 100644 --- a/src/GraphQLParser/Location.cs +++ b/src/GraphQLParser/Location.cs @@ -7,7 +7,7 @@ namespace GraphQLParser /// public readonly struct Location { - private static readonly Regex _lineRegex = new Regex("\r\n|[\n\r]", RegexOptions.ECMAScript); + private static readonly Regex _lineRegex = new("\r\n|[\n\r]", RegexOptions.ECMAScript); /// /// Creates location from a given sequence of characters and a linear character position. diff --git a/src/GraphQLParser/NodeHelper.cs b/src/GraphQLParser/NodeHelper.cs index 8ad4765f..aa69ccf2 100644 --- a/src/GraphQLParser/NodeHelper.cs +++ b/src/GraphQLParser/NodeHelper.cs @@ -5,6 +5,8 @@ namespace GraphQLParser { internal static class NodeHelper { + #region ASTNodes that can not have comments, only locations + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static GraphQLComment CreateGraphQLComment(IgnoreOptions options) { @@ -41,6 +43,10 @@ public static GraphQLDescription CreateGraphQLDescription(IgnoreOptions options) }; } + #endregion + + #region ASTNodes that can have comments and locations + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static GraphQLArgument CreateGraphQLArgument(IgnoreOptions options) { @@ -150,14 +156,14 @@ public static GraphQLVariable CreateGraphQLVariable(IgnoreOptions options) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static GraphQLOperationTypeDefinition CreateGraphQLOperationTypeDefinition(IgnoreOptions options) + public static GraphQLRootOperationTypeDefinition CreateGraphQLOperationTypeDefinition(IgnoreOptions options) { return options switch { - IgnoreOptions.All => new GraphQLOperationTypeDefinition(), - IgnoreOptions.Comments => new GraphQLOperationTypeDefinitionWithLocation(), - IgnoreOptions.Locations => new GraphQLOperationTypeDefinitionWithComment(), - _ => new GraphQLOperationTypeDefinitionFull(), + IgnoreOptions.All => new GraphQLRootOperationTypeDefinition(), + IgnoreOptions.Comments => new GraphQLRootOperationTypeDefinitionWithLocation(), + IgnoreOptions.Locations => new GraphQLRootOperationTypeDefinitionWithComment(), + _ => new GraphQLRootOperationTypeDefinitionFull(), }; } @@ -222,14 +228,14 @@ public static GraphQLDirectiveDefinition CreateGraphQLDirectiveDefinition(Ignore } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static GraphQLFieldSelection CreateGraphQLFieldSelection(IgnoreOptions options) + public static GraphQLField CreateGraphQLField(IgnoreOptions options) { return options switch { - IgnoreOptions.All => new GraphQLFieldSelection(), - IgnoreOptions.Comments => new GraphQLFieldSelectionWithLocation(), - IgnoreOptions.Locations => new GraphQLFieldSelectionWithComment(), - _ => new GraphQLFieldSelectionFull(), + IgnoreOptions.All => new GraphQLField(), + IgnoreOptions.Comments => new GraphQLFieldWithLocation(), + IgnoreOptions.Locations => new GraphQLFieldWithComment(), + _ => new GraphQLFieldFull(), }; } @@ -412,5 +418,7 @@ public static GraphQLInputValueDefinition CreateGraphQLInputValueDefinition(Igno _ => new GraphQLInputValueDefinitionFull(), }; } + + #endregion } } diff --git a/src/GraphQLParser/Parser.cs b/src/GraphQLParser/Parser.cs index 11af5898..f8cf10cf 100644 --- a/src/GraphQLParser/Parser.cs +++ b/src/GraphQLParser/Parser.cs @@ -13,6 +13,7 @@ public static class Parser /// Input data as a sequence of characters. /// Parser options. /// AST (Abstract Syntax Tree) for GraphQL document. - public static GraphQLDocument Parse(ROM source, ParserOptions options = default) => new ParserContext(source, options).Parse(); + public static GraphQLDocument Parse(ROM source, ParserOptions options = default) + => new ParserContext(source, options).ParseDocument(); } } diff --git a/src/GraphQLParser/ParserContext.Parse.cs b/src/GraphQLParser/ParserContext.Parse.cs index af3715f9..97562090 100644 --- a/src/GraphQLParser/ParserContext.Parse.cs +++ b/src/GraphQLParser/ParserContext.Parse.cs @@ -7,29 +7,60 @@ namespace GraphQLParser // WARNING: mutable struct, pass it by reference to those methods that will change it internal partial struct ParserContext { - public GraphQLDocument Parse() => ParseDocument(); + // http://spec.graphql.org/October2021/#Document + public GraphQLDocument ParseDocument() + { + + int start = _currentToken.Start; + var definitions = ParseDefinitionsIfNotEOF(); + + SetCurrentComment(null); // push current (last) comment into _unattachedComments + + _document.Location = new GraphQLLocation + ( + start, + // Formally, to denote the end of the document, it is better to use _prevToken.End, + // since _prevToken represents some real meaningful token; _currentToken here is always EOF. + // EOF is a technical token with length = 0, _prevToken.End and _currentToken.End have the same value here. + _prevToken.End // equals to _currentToken.End (EOF) + ); + _document.Definitions = definitions; + _document.UnattachedComments = _unattachedComments; + return _document; + } - private GraphQLNamedType? ParseTypeCondition() + // http://spec.graphql.org/October2021/#TypeCondition + private GraphQLNamedType? ParseTypeCondition(bool optional) { - GraphQLNamedType? typeCondition = null; - if (_currentToken.Value == "on") + if (optional) { - Advance(); - typeCondition = ParseNamedType(); + GraphQLNamedType? typeCondition = null; + if (_currentToken.Value == "on") + { + Advance(); + typeCondition = ParseNamedType(); + } + return typeCondition; + } + else + { + ExpectKeyword("on"); + return ParseNamedType(); } - - return typeCondition; } + // http://spec.graphql.org/October2021/#Argument private GraphQLArgument ParseArgument() { int start = _currentToken.Start; - var comment = GetComment(); var arg = NodeHelper.CreateGraphQLArgument(_ignoreOptions); + arg.Comment = GetComment(); arg.Name = ParseName(); - arg.Value = ExpectColonAndParseValueLiteral(false); - arg.Comment = comment; + + Expect(TokenKind.COLON); + + arg.Value = ParseValueLiteral(false); arg.Location = GetLocation(start); return arg; } @@ -69,22 +100,22 @@ private GraphQLArgument ParseArgument() : null; } - private GraphQLValue ParseBooleanValue(Token token) + // http://spec.graphql.org/October2021/#BooleanValue + private GraphQLValue ParseBooleanValue() { - var comment = GetComment(); + var token = _currentToken; + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.BooleanValue); + val.Comment = GetComment(); + Advance(); - var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.BooleanValue); val.Value = token.Value; - val.Comment = comment; val.Location = GetLocation(token.Start); return val; } private ASTNode ParseDefinition() { - ParseComment(); - if (Peek(TokenKind.BRACE_L)) { return ParseOperationDefinition(); @@ -128,21 +159,22 @@ private List ParseDefinitionsIfNotEOF() return result; } - private GraphQLComment? ParseComment() + // http://spec.graphql.org/October2021/#Comment + private void ParseComment() { // skip comments if (_ignoreOptions.HasFlag(IgnoreOptions.Comments)) { while (Peek(TokenKind.COMMENT)) { - Advance(); + Advance(fromParseComment: true); } - return null; + return; } if (!Peek(TokenKind.COMMENT)) { - return null; + return; } var text = new List(); @@ -153,7 +185,7 @@ private List ParseDefinitionsIfNotEOF() { text.Add(_currentToken.Value); end = _currentToken.End; - Advance(); + Advance(fromParseComment: true); } while (_currentToken.Kind == TokenKind.COMMENT); @@ -168,12 +200,10 @@ private List ParseDefinitionsIfNotEOF() { var (owner, result) = text.Concat(); comment.Text = result; - (_document!.RentedMemoryTracker ??= new List<(System.Buffers.IMemoryOwner, ASTNode)>()).Add((owner, comment)); + (_document.RentedMemoryTracker ??= new List<(System.Buffers.IMemoryOwner, ASTNode)>()).Add((owner, comment)); } SetCurrentComment(comment); - - return comment; } private void SetCurrentComment(GraphQLComment? comment) @@ -191,21 +221,23 @@ private void SetCurrentComment(GraphQLComment? comment) return ret; } + // http://spec.graphql.org/October2021/#Directive private GraphQLDirective ParseDirective() { int start = _currentToken.Start; + var dir = NodeHelper.CreateGraphQLDirective(_ignoreOptions); + dir.Comment = GetComment(); + Expect(TokenKind.AT); - var dir = NodeHelper.CreateGraphQLDirective(_ignoreOptions); dir.Name = ParseName(); dir.Arguments = ParseArguments(); - dir.Comment = null; //TODO: ???? dir.Location = GetLocation(start); return dir; } /// - /// http://spec.graphql.org/draft/#DirectiveDefinition + /// http://spec.graphql.org/October2021/#DirectiveDefinition /// DirectiveDefinition: /// Description(opt) directive @ Name ArgumentsDefinition(opt) repeatable(opt) on DirectiveLocations /// @@ -217,7 +249,6 @@ private GraphQLDirectiveDefinition ParseDirectiveDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); ExpectKeyword("directive"); @@ -282,6 +313,7 @@ private List ParseDirectiveLocations() return locations; } + // http://spec.graphql.org/October2021/#Directives private List? ParseDirectives() { List? directives = null; @@ -291,28 +323,7 @@ private List ParseDirectiveLocations() return directives; } - private GraphQLDocument ParseDocument() - { - _document = NodeHelper.CreateGraphQLDocument(_ignoreOptions); - - int start = _currentToken.Start; - var definitions = ParseDefinitionsIfNotEOF(); - - SetCurrentComment(null); - - _document.Location = new GraphQLLocation - ( - start, - // Formally, to denote the end of the document, it is better to use _prevToken.End, - // since _prevToken represents some real meaningful token; _currentToken here is always EOF. - // EOF is a technical token with length = 0, _prevToken.End and _currentToken.End have the same value here. - _prevToken.End // equals to _currentToken.End (EOF) - ); - _document.Definitions = definitions; - _document.UnattachedComments = _unattachedComments; - return _document; - } - + // http://spec.graphql.org/October2021/#EnumTypeDefinition private GraphQLEnumTypeDefinition ParseEnumTypeDefinition() { int start = _currentToken.Start; @@ -320,7 +331,6 @@ private GraphQLEnumTypeDefinition ParseEnumTypeDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); ExpectKeyword("enum"); @@ -335,18 +345,21 @@ private GraphQLEnumTypeDefinition ParseEnumTypeDefinition() return def; } - private GraphQLValue ParseEnumValue(Token token) + // http://spec.graphql.org/October2021/#EnumValue + private GraphQLValue ParseEnumValue() { - var comment = GetComment(); + var token = _currentToken; + var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.EnumValue); + val.Comment = GetComment(); + Advance(); - var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.EnumValue); val.Value = token.Value; - val.Comment = comment; val.Location = GetLocation(token.Start); return val; } + // http://spec.graphql.org/October2021/#EnumValueDefinition private GraphQLEnumValueDefinition ParseEnumValueDefinition() { int start = _currentToken.Start; @@ -354,7 +367,6 @@ private GraphQLEnumValueDefinition ParseEnumValueDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); @@ -367,6 +379,7 @@ private GraphQLEnumValueDefinition ParseEnumValueDefinition() return def; } + // http://spec.graphql.org/October2021/#FieldDefinition private GraphQLFieldDefinition ParseFieldDefinition() { int start = _currentToken.Start; @@ -374,7 +387,6 @@ private GraphQLFieldDefinition ParseFieldDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); @@ -393,7 +405,8 @@ private GraphQLFieldDefinition ParseFieldDefinition() return def; } - private GraphQLFieldSelection ParseFieldSelection() + // http://spec.graphql.org/October2021/#Field + private GraphQLField ParseField() { int start = _currentToken.Start; var comment = GetComment(); @@ -412,18 +425,19 @@ private GraphQLFieldSelection ParseFieldSelection() name = nameOrAlias; } - var sel = NodeHelper.CreateGraphQLFieldSelection(_ignoreOptions); - sel.Alias = alias; - sel.Name = name; - sel.Arguments = ParseArguments(); - sel.Directives = ParseDirectives(); - sel.SelectionSet = Peek(TokenKind.BRACE_L) ? ParseSelectionSet() : null; - sel.Comment = comment; - sel.Location = GetLocation(start); - return sel; + var field = NodeHelper.CreateGraphQLField(_ignoreOptions); + field.Alias = alias; + field.Name = name; + field.Arguments = ParseArguments(); + field.Directives = ParseDirectives(); + field.SelectionSet = Peek(TokenKind.BRACE_L) ? ParseSelectionSet() : null; + field.Comment = comment; + field.Location = GetLocation(start); + return field; } - private GraphQLValue ParseFloat(/*bool isConstant*/) + // http://spec.graphql.org/October2021/#FloatValue + private GraphQLValue ParseFloatValue(/*bool isConstant*/) { var token = _currentToken; var comment = GetComment(); @@ -443,11 +457,12 @@ private ASTNode ParseFragment() Expect(TokenKind.SPREAD); return Peek(TokenKind.NAME) && _currentToken.Value != "on" - ? CreateGraphQLFragmentSpread(start, comment) - : CreateInlineFragment(start, comment); + ? ParseFragmentSpread(start, comment) + : ParseInlineFragment(start, comment); } - private ASTNode CreateGraphQLFragmentSpread(int start, GraphQLComment? comment) + // http://spec.graphql.org/October2021/#FragmentSpread + private GraphQLFragmentSpread ParseFragmentSpread(int start, GraphQLComment? comment) { var spread = NodeHelper.CreateGraphQLFragmentSpread(_ignoreOptions); spread.Name = ParseFragmentName(); @@ -457,10 +472,11 @@ private ASTNode CreateGraphQLFragmentSpread(int start, GraphQLComment? comment) return spread; } - private ASTNode CreateInlineFragment(int start, GraphQLComment? comment) + // http://spec.graphql.org/October2021/#InlineFragment + private GraphQLInlineFragment ParseInlineFragment(int start, GraphQLComment? comment) { var frag = NodeHelper.CreateGraphQLInlineFragment(_ignoreOptions); - frag.TypeCondition = ParseTypeCondition(); + frag.TypeCondition = ParseTypeCondition(optional: true); frag.Directives = ParseDirectives(); frag.SelectionSet = ParseSelectionSet(); frag.Comment = comment; @@ -468,6 +484,7 @@ private ASTNode CreateInlineFragment(int start, GraphQLComment? comment) return frag; } + // http://spec.graphql.org/October2021/#FragmentDefinition private GraphQLFragmentDefinition ParseFragmentDefinition() { int start = _currentToken.Start; @@ -476,7 +493,7 @@ private GraphQLFragmentDefinition ParseFragmentDefinition() var def = NodeHelper.CreateGraphQLFragmentDefinition(_ignoreOptions); def.Name = ParseFragmentName(); - def.TypeCondition = ExpectOnKeywordAndParseNamedType(); + def.TypeCondition = ParseTypeCondition(optional: false); def.Directives = ParseDirectives(); def.SelectionSet = ParseSelectionSet(); def.Comment = comment; @@ -484,6 +501,7 @@ private GraphQLFragmentDefinition ParseFragmentDefinition() return def; } + // http://spec.graphql.org/October2021/#FragmentName private GraphQLName ParseFragmentName() { if (_currentToken.Value == "on") @@ -499,6 +517,7 @@ private void Throw_From_ParseFragmentName() throw new GraphQLSyntaxErrorException($"Unexpected {_currentToken}", _source, _currentToken.Start); } + // http://spec.graphql.org/October2021/#ImplementsInterfaces private List? ParseImplementsInterfaces() { List? types = null; @@ -521,6 +540,7 @@ private void Throw_From_ParseFragmentName() return types; } + // http://spec.graphql.org/October2021/#InputObjectTypeDefinition private GraphQLInputObjectTypeDefinition ParseInputObjectTypeDefinition() { int start = _currentToken.Start; @@ -528,7 +548,6 @@ private GraphQLInputObjectTypeDefinition ParseInputObjectTypeDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); ExpectKeyword("input"); @@ -543,6 +562,7 @@ private GraphQLInputObjectTypeDefinition ParseInputObjectTypeDefinition() return def; } + // http://spec.graphql.org/October2021/#InputValueDefinition private GraphQLInputValueDefinition ParseInputValueDef() { int start = _currentToken.Start; @@ -550,7 +570,6 @@ private GraphQLInputValueDefinition ParseInputValueDef() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); var name = ParseName(); @@ -567,7 +586,8 @@ private GraphQLInputValueDefinition ParseInputValueDef() return def; } - private GraphQLValue ParseInt(/*bool isConstant*/) + // http://spec.graphql.org/October2021/#IntValue + private GraphQLValue ParseIntValue(/*bool isConstant*/) { var token = _currentToken; var comment = GetComment(); @@ -580,6 +600,7 @@ private GraphQLValue ParseInt(/*bool isConstant*/) return val; } + // http://spec.graphql.org/October2021/#InterfaceTypeDefinition private GraphQLInterfaceTypeDefinition ParseInterfaceTypeDefinition() { int start = _currentToken.Start; @@ -587,7 +608,6 @@ private GraphQLInterfaceTypeDefinition ParseInterfaceTypeDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); ExpectKeyword("interface"); @@ -602,7 +622,8 @@ private GraphQLInterfaceTypeDefinition ParseInterfaceTypeDefinition() return def; } - private GraphQLValue ParseList(bool isConstant) + // http://spec.graphql.org/October2021/#ListValue + private GraphQLValue ParseListValue(bool isConstant) { int start = _currentToken.Start; var comment = GetComment(); @@ -619,6 +640,7 @@ private GraphQLValue ParseList(bool isConstant) return val; } + // http://spec.graphql.org/October2021/#Name private GraphQLName ParseName() { int start = _currentToken.Start; @@ -723,12 +745,13 @@ private GraphQLName ParseName() return null; } + // http://spec.graphql.org/October2021/#NamedType private GraphQLNamedType ParseNamedType() { int start = _currentToken.Start; var named = NodeHelper.CreateGraphQLNamedType(_ignoreOptions); + named.Comment = GetComment(); named.Name = ParseName(); - named.Comment = null; //TODO: ???? named.Location = GetLocation(start); return named; } @@ -739,13 +762,13 @@ private GraphQLValue ParseNameValue(/*bool isConstant*/) if (token.Value == "true" || token.Value == "false") { - return ParseBooleanValue(token); + return ParseBooleanValue(); } else if (!token.Value.IsEmpty) { return token.Value == "null" - ? ParseNullValue(token) - : ParseEnumValue(token); + ? ParseNullValue() + : ParseEnumValue(); } return Throw_From_ParseNameValue(); @@ -756,7 +779,8 @@ private GraphQLValue Throw_From_ParseNameValue() throw new GraphQLSyntaxErrorException($"Unexpected {_currentToken}", _source, _currentToken.Start); } - private GraphQLValue ParseObject(bool isConstant) + // http://spec.graphql.org/October2021/#ObjectValue + private GraphQLValue ParseObjectValue(bool isConstant) { int start = _currentToken.Start; var comment = GetComment(); @@ -768,24 +792,31 @@ private GraphQLValue ParseObject(bool isConstant) return val; } - private GraphQLValue ParseNullValue(Token token) + // http://spec.graphql.org/October2021/#NullValue + private GraphQLValue ParseNullValue() { - var comment = GetComment(); - Advance(); + var token = _currentToken; var val = NodeHelper.CreateGraphQLScalarValue(_ignoreOptions, ASTNodeKind.NullValue); + val.Comment = GetComment(); val.Value = token.Value; - val.Comment = comment; + + Advance(); + val.Location = GetLocation(token.Start); return val; } + // http://spec.graphql.org/October2021/#ObjectField private GraphQLObjectField ParseObjectField(bool isConstant) { int start = _currentToken.Start; var comment = GetComment(); var field = NodeHelper.CreateGraphQLObjectField(_ignoreOptions); field.Name = ParseName(); - field.Value = ExpectColonAndParseValueLiteral(isConstant); + + Expect(TokenKind.COLON); + + field.Value = ParseValueLiteral(isConstant); field.Comment = comment; field.Location = GetLocation(start); return field; @@ -802,6 +833,7 @@ private List ParseObjectFields(bool isConstant) return fields; } + // http://spec.graphql.org/October2021/#ObjectTypeDefinition private GraphQLObjectTypeDefinition ParseObjectTypeDefinition() { int start = _currentToken.Start; @@ -809,7 +841,6 @@ private GraphQLObjectTypeDefinition ParseObjectTypeDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); @@ -826,40 +857,33 @@ private GraphQLObjectTypeDefinition ParseObjectTypeDefinition() return def; } + // http://spec.graphql.org/October2021/#OperationDefinition private ASTNode ParseOperationDefinition() { int start = _currentToken.Start; - - return Peek(TokenKind.BRACE_L) - ? CreateOperationDefinition(start) - : CreateOperationDefinition(start, ParseOperationType(), Peek(TokenKind.NAME) ? ParseName() : null); // Peek(TokenKind.NAME) because of anonymous query - } - - private ASTNode CreateOperationDefinition(int start) - { - var comment = GetComment(); var def = NodeHelper.CreateGraphQLOperationDefinition(_ignoreOptions); - def.Operation = OperationType.Query; - def.SelectionSet = ParseSelectionSet(); - def.Comment = comment; - def.Location = GetLocation(start); - return def; - } + def.Comment = GetComment(); - private ASTNode CreateOperationDefinition(int start, OperationType operation, GraphQLName? name) - { - var comment = GetComment(); - var def = NodeHelper.CreateGraphQLOperationDefinition(_ignoreOptions); - def.Operation = operation; - def.Name = name; - def.VariableDefinitions = ParseVariableDefinitions(); - def.Directives = ParseDirectives(); - def.SelectionSet = ParseSelectionSet(); - def.Comment = comment; - def.Location = GetLocation(start); - return def; + if (Peek(TokenKind.BRACE_L)) + { + def.Operation = OperationType.Query; + def.SelectionSet = ParseSelectionSet(); + def.Location = GetLocation(start); + return def; + } + else + { + def.Operation = ParseOperationType(); + def.Name = Peek(TokenKind.NAME) ? ParseName() : null; // Peek(TokenKind.NAME) because of anonymous query + def.VariableDefinitions = ParseVariableDefinitions(); + def.Directives = ParseDirectives(); + def.SelectionSet = ParseSelectionSet(); + def.Location = GetLocation(start); + return def; + } } + // http://spec.graphql.org/October2021/#OperationType private OperationType ParseOperationType() { var token = _currentToken; @@ -874,21 +898,22 @@ private OperationType ParseOperationType() return OperationType.Query; } - private GraphQLOperationTypeDefinition ParseOperationTypeDefinition() + // http://spec.graphql.org/October2021/#RootOperationTypeDefinition + private GraphQLRootOperationTypeDefinition ParseRootOperationTypeDefinition() { int start = _currentToken.Start; - var operation = ParseOperationType(); + var def = NodeHelper.CreateGraphQLOperationTypeDefinition(_ignoreOptions); + def.Comment = GetComment(); + def.Operation = ParseOperationType(); + Expect(TokenKind.COLON); - var type = ParseNamedType(); - var def = NodeHelper.CreateGraphQLOperationTypeDefinition(_ignoreOptions); - def.Operation = operation; - def.Type = type; - def.Comment = null; //TODO: ???? + def.Type = ParseNamedType(); def.Location = GetLocation(start); return def; } + // http://spec.graphql.org/October2021/#ScalarTypeDefinition private GraphQLScalarTypeDefinition ParseScalarTypeDefinition() { int start = _currentToken.Start; @@ -896,7 +921,6 @@ private GraphQLScalarTypeDefinition ParseScalarTypeDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); ExpectKeyword("scalar"); @@ -912,6 +936,7 @@ private GraphQLScalarTypeDefinition ParseScalarTypeDefinition() return def; } + // http://spec.graphql.org/October2021/#SchemaDefinition private GraphQLSchemaDefinition ParseSchemaDefinition() { int start = _currentToken.Start; @@ -919,12 +944,11 @@ private GraphQLSchemaDefinition ParseSchemaDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); ExpectKeyword("schema"); var directives = ParseDirectives(); - var operationTypes = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseOperationTypeDefinition(), TokenKind.BRACE_R); + var operationTypes = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseRootOperationTypeDefinition(), TokenKind.BRACE_R); var def = NodeHelper.CreateGraphQLSchemaDefinition(_ignoreOptions); def.Directives = directives; @@ -935,24 +959,27 @@ private GraphQLSchemaDefinition ParseSchemaDefinition() return def; } + // http://spec.graphql.org/October2021/#Selection private ASTNode ParseSelection() { return Peek(TokenKind.SPREAD) ? ParseFragment() : - ParseFieldSelection(); + ParseField(); } + // http://spec.graphql.org/October2021/#SelectionSet private GraphQLSelectionSet ParseSelectionSet() { int start = _currentToken.Start; var selection = NodeHelper.CreateGraphQLSelectionSet(_ignoreOptions); + selection.Comment = GetComment(); selection.Selections = OneOrMore(TokenKind.BRACE_L, (ref ParserContext context) => context.ParseSelection(), TokenKind.BRACE_R); - selection.Comment = null; //TODO: ??? selection.Location = GetLocation(start); return selection; } - private GraphQLScalarValue ParseString(/*bool isConstant*/) + // http://spec.graphql.org/October2021/#StringValue + private GraphQLScalarValue ParseStringValue(/*bool isConstant*/) { var token = _currentToken; var comment = GetComment(); @@ -965,6 +992,7 @@ private GraphQLScalarValue ParseString(/*bool isConstant*/) return val; } + // http://spec.graphql.org/October2021/#Description private GraphQLDescription ParseDescription() { var token = _currentToken; @@ -975,17 +1003,22 @@ private GraphQLDescription ParseDescription() return descr; } + // http://spec.graphql.org/October2021/#Type private GraphQLType ParseType() { GraphQLType type; int start = _currentToken.Start; - if (Skip(TokenKind.BRACKET_L)) + if (Peek(TokenKind.BRACKET_L)) { - type = ParseType(); - Expect(TokenKind.BRACKET_R); var listType = NodeHelper.CreateGraphQLListType(_ignoreOptions); - listType.Type = type; - listType.Comment = null; //TODO: ??????????????? + listType.Comment = GetComment(); + + Advance(); // skip BRACKET_L + + listType.Type = ParseType(); + + Expect(TokenKind.BRACKET_R); + listType.Location = GetLocation(start); type = listType; } @@ -999,11 +1032,14 @@ private GraphQLType ParseType() var nonNull = NodeHelper.CreateGraphQLNonNullType(_ignoreOptions); nonNull.Type = type; - nonNull.Comment = null; /////TODO: ???? + // move comment from wrapped type to wrapping type + nonNull.Comment = type.Comment; + type.Comment = null; nonNull.Location = GetLocation(start); return nonNull; } + // TODO: change name, spec does not containt term TypeExtensionDefinition private GraphQLTypeExtensionDefinition ParseTypeExtensionDefinition() { int start = _currentToken.Start; @@ -1020,8 +1056,11 @@ private GraphQLTypeExtensionDefinition ParseTypeExtensionDefinition() return def; } - private List ParseUnionMembers() + // http://spec.graphql.org/October2021/#UnionMemberTypes + private List ParseUnionMemberTypes() { + Expect(TokenKind.EQUALS); + var members = new List(); // Union members may be defined with an optional leading | character @@ -1037,6 +1076,7 @@ private List ParseUnionMembers() return members; } + // http://spec.graphql.org/October2021/#UnionTypeDefinition private GraphQLUnionTypeDefinition ParseUnionTypeDefinition() { int start = _currentToken.Start; @@ -1044,14 +1084,12 @@ private GraphQLUnionTypeDefinition ParseUnionTypeDefinition() if (Peek(TokenKind.STRING)) { description = ParseDescription(); - ParseComment(); } var comment = GetComment(); ExpectKeyword("union"); var name = ParseName(); var directives = ParseDirectives(); - Expect(TokenKind.EQUALS); - var types = ParseUnionMembers(); + var types = ParseUnionMemberTypes(); var def = NodeHelper.CreateGraphQLUnionTypeDefinition(_ignoreOptions); def.Name = name; @@ -1065,15 +1103,13 @@ private GraphQLUnionTypeDefinition ParseUnionTypeDefinition() private GraphQLValue ParseValueLiteral(bool isConstant) { - ParseComment(); - return _currentToken.Kind switch { - TokenKind.BRACKET_L => ParseList(isConstant), - TokenKind.BRACE_L => ParseObject(isConstant), - TokenKind.INT => ParseInt(/*isConstant*/), - TokenKind.FLOAT => ParseFloat(/*isConstant*/), - TokenKind.STRING => ParseString(/*isConstant*/), + TokenKind.BRACKET_L => ParseListValue(isConstant), + TokenKind.BRACE_L => ParseObjectValue(isConstant), + TokenKind.INT => ParseIntValue(/*isConstant*/), + TokenKind.FLOAT => ParseFloatValue(/*isConstant*/), + TokenKind.STRING => ParseStringValue(/*isConstant*/), TokenKind.NAME => ParseNameValue(/*isConstant*/), TokenKind.DOLLAR when !isConstant => ParseVariable(), _ => Throw_From_ParseValueLiteral() @@ -1085,6 +1121,7 @@ private GraphQLValue Throw_From_ParseValueLiteral() throw new GraphQLSyntaxErrorException($"Unexpected {_currentToken}", _source, _currentToken.Start); } + // http://spec.graphql.org/October2021/#Variable private GraphQLVariable ParseVariable() { int start = _currentToken.Start; @@ -1098,6 +1135,7 @@ private GraphQLVariable ParseVariable() return variable; } + // http://spec.graphql.org/October2021/#VariableDefinition private GraphQLVariableDefinition ParseVariableDefinition() { int start = _currentToken.Start; @@ -1105,13 +1143,17 @@ private GraphQLVariableDefinition ParseVariableDefinition() var def = NodeHelper.CreateGraphQLVariableDefinition(_ignoreOptions); def.Variable = ParseVariable(); - def.Type = ExpectColonAndParseType(); + + Expect(TokenKind.COLON); + + def.Type = ParseType(); def.DefaultValue = Skip(TokenKind.EQUALS) ? ParseValueLiteral(true) : null; def.Comment = comment; def.Location = GetLocation(start); return def; } + // http://spec.graphql.org/October2021/#VariableDefinitions private List? ParseVariableDefinitions() { return Peek(TokenKind.PAREN_L) ? diff --git a/src/GraphQLParser/ParserContext.cs b/src/GraphQLParser/ParserContext.cs index 1275d334..1179b36f 100644 --- a/src/GraphQLParser/ParserContext.cs +++ b/src/GraphQLParser/ParserContext.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics; using GraphQLParser.AST; using GraphQLParser.Exceptions; @@ -15,27 +16,28 @@ internal partial struct ParserContext private List? _unattachedComments; private Token _currentToken; private Token _prevToken; - private GraphQLDocument? _document; + private readonly GraphQLDocument _document; public ParserContext(ROM source, ParserOptions options) { - _document = null; _currentComment = null; _unattachedComments = null; _source = source; _ignoreOptions = options.Ignore; - - _currentToken = Lexer.Lex(source); - _prevToken = new Token + // should create document beforehand to use RentedMemoryTracker while parsing coomments + _document = NodeHelper.CreateGraphQLDocument(options.Ignore); + _currentToken = _prevToken = new Token ( TokenKind.UNKNOWN, default, 0, 0 ); + + Advance(); } - private GraphQLLocation GetLocation(int start) + private readonly GraphQLLocation GetLocation(int start) { return new GraphQLLocation ( @@ -49,8 +51,6 @@ private GraphQLLocation GetLocation(int start) { Expect(open); - ParseComment(); - List? nodes = null; while (!Skip(close)) (nodes ??= new List()).Add(next(ref this)); @@ -63,8 +63,6 @@ private List OneOrMore(TokenKind open, ParseCallback next, TokenKind cl { Expect(open); - ParseComment(); - var nodes = new List { next(ref this) }; while (!Skip(close)) nodes.Add(next(ref this)); @@ -72,11 +70,11 @@ private List OneOrMore(TokenKind open, ParseCallback next, TokenKind cl return nodes; } - private bool Peek(TokenKind kind) => _currentToken.Kind == kind; + private readonly bool Peek(TokenKind kind) => _currentToken.Kind == kind; private bool Skip(TokenKind kind) { - ParseComment(); + Debug.Assert(kind != TokenKind.COMMENT && kind != TokenKind.UNKNOWN); bool isCurrentTokenMatching = _currentToken.Kind == kind; @@ -88,13 +86,16 @@ private bool Skip(TokenKind kind) return isCurrentTokenMatching; } - private void Advance() + private void Advance(bool fromParseComment = false) { // We should not advance further if we have already reached the EOF. if (_currentToken.Kind != TokenKind.EOF) { _prevToken = _currentToken; _currentToken = Lexer.Lex(_source, _currentToken.End); + // Comments may appear everywhere + if (!fromParseComment) + ParseComment(); } } @@ -127,23 +128,5 @@ private void Throw_From_ExpectKeyword(string keyword) { throw new GraphQLSyntaxErrorException($"Expected \"{keyword}\", found Name \"{_currentToken.Value}\"", _source, _currentToken.Start); } - - private GraphQLNamedType ExpectOnKeywordAndParseNamedType() - { - ExpectKeyword("on"); - return ParseNamedType(); - } - - private GraphQLType ExpectColonAndParseType() - { - Expect(TokenKind.COLON); - return ParseType(); - } - - private GraphQLValue ExpectColonAndParseValueLiteral(bool isConstant) - { - Expect(TokenKind.COLON); - return ParseValueLiteral(isConstant); - } } } diff --git a/src/GraphQLParser/ROM.cs b/src/GraphQLParser/ROM.cs index b79b67a8..f5ca703a 100644 --- a/src/GraphQLParser/ROM.cs +++ b/src/GraphQLParser/ROM.cs @@ -47,7 +47,7 @@ public bool Equals(ROM other) } /// - public override int GetHashCode() //TODO: find a better implementation + public override int GetHashCode() // TODO: find a better implementation { if (_memory.Length == 0) return 0; @@ -80,7 +80,7 @@ public override int GetHashCode() //TODO: find a better implementation /// /// Implicitly casts ReadOnlyMemory<char> to . /// - public static implicit operator ROM(ReadOnlyMemory memory) => new ROM(memory); + public static implicit operator ROM(ReadOnlyMemory memory) => new(memory); /// /// Implicitly casts to ReadOnlyMemory<char>. @@ -95,7 +95,7 @@ public override int GetHashCode() //TODO: find a better implementation /// /// Implicitly casts Memory<char> to . /// - public static implicit operator ROM(Memory memory) => new ROM(memory); + public static implicit operator ROM(Memory memory) => new(memory); /// /// Implicitly casts string to . From 54f36b15f5416e21bcebcd05ad5d4c1cefd58e76 Mon Sep 17 00:00:00 2001 From: Ivan Maximov Date: Wed, 10 Nov 2021 00:45:14 +0300 Subject: [PATCH 4/4] typo --- src/GraphQLParser/ParserContext.Parse.cs | 1 - src/GraphQLParser/ParserContext.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GraphQLParser/ParserContext.Parse.cs b/src/GraphQLParser/ParserContext.Parse.cs index 97562090..8d0a8920 100644 --- a/src/GraphQLParser/ParserContext.Parse.cs +++ b/src/GraphQLParser/ParserContext.Parse.cs @@ -10,7 +10,6 @@ internal partial struct ParserContext // http://spec.graphql.org/October2021/#Document public GraphQLDocument ParseDocument() { - int start = _currentToken.Start; var definitions = ParseDefinitionsIfNotEOF(); diff --git a/src/GraphQLParser/ParserContext.cs b/src/GraphQLParser/ParserContext.cs index 1179b36f..c46bf4f3 100644 --- a/src/GraphQLParser/ParserContext.cs +++ b/src/GraphQLParser/ParserContext.cs @@ -24,7 +24,7 @@ public ParserContext(ROM source, ParserOptions options) _unattachedComments = null; _source = source; _ignoreOptions = options.Ignore; - // should create document beforehand to use RentedMemoryTracker while parsing coomments + // should create document beforehand to use RentedMemoryTracker while parsing comments _document = NodeHelper.CreateGraphQLDocument(options.Ignore); _currentToken = _prevToken = new Token (