diff --git a/crates/apollo-compiler/src/ast/from_cst.rs b/crates/apollo-compiler/src/ast/from_cst.rs index c39788cf6..b30de44a7 100644 --- a/crates/apollo-compiler/src/ast/from_cst.rs +++ b/crates/apollo-compiler/src/ast/from_cst.rs @@ -125,6 +125,7 @@ impl Convert for cst::OperationDefinition { ast::OperationType::Query }; Some(Self::Target { + description: self.description().convert(file_id)?, operation_type, name: self.name().convert(file_id)?, variables: collect_opt(file_id, self.variable_definitions(), |x| { @@ -147,6 +148,7 @@ impl Convert for cst::FragmentDefinition { fn convert(&self, file_id: FileId) -> Option { Some(Self::Target { + description: self.description().convert(file_id)?, name: self.fragment_name()?.name()?.convert(file_id)?, type_condition: self.type_condition()?.convert(file_id)?, directives: ast::DirectiveList(collect_opt(file_id, self.directives(), |x| { @@ -530,6 +532,7 @@ impl Convert for cst::VariableDefinition { }; let ty = &self.ty()?; Some(Self::Target { + description: self.description().convert(file_id)?, name: self.variable()?.name()?.convert(file_id)?, ty: with_location(file_id, ty.syntax(), ty.convert(file_id)?), default_value, diff --git a/crates/apollo-compiler/src/ast/mod.rs b/crates/apollo-compiler/src/ast/mod.rs index 1112a5cb3..71476bbdd 100644 --- a/crates/apollo-compiler/src/ast/mod.rs +++ b/crates/apollo-compiler/src/ast/mod.rs @@ -116,6 +116,7 @@ pub enum Definition { /// [_OperationDefinition_](https://spec.graphql.org/draft/#OperationDefinition). #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct OperationDefinition { + pub description: Option>, pub operation_type: OperationType, pub name: Option, pub variables: Vec>, @@ -127,6 +128,7 @@ pub struct OperationDefinition { /// [_FragmentDefinition_](https://spec.graphql.org/draft/#FragmentDefinition). #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct FragmentDefinition { + pub description: Option>, pub name: Name, pub type_condition: NamedType, pub directives: DirectiveList, @@ -335,6 +337,7 @@ pub enum DirectiveLocation { /// in an [`OperationDefinition`]. #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct VariableDefinition { + pub description: Option>, pub name: Name, pub ty: Node, pub default_value: Option>, diff --git a/crates/apollo-compiler/src/ast/serialize.rs b/crates/apollo-compiler/src/ast/serialize.rs index 819b17332..0ed7b049b 100644 --- a/crates/apollo-compiler/src/ast/serialize.rs +++ b/crates/apollo-compiler/src/ast/serialize.rs @@ -194,12 +194,14 @@ impl OperationDefinition { fn serialize_impl(&self, state: &mut State) -> fmt::Result { // Deconstruct to get a warning if we forget to serialize something let Self { + description, operation_type, name, variables, directives, selection_set, } = self; + serialize_description(state, description)?; // Only use shorthand when this is the first item. // If not, it might be following a `[lookahead != "{"]` grammar production let shorthand = state.output_empty @@ -230,11 +232,13 @@ impl OperationDefinition { impl FragmentDefinition { fn serialize_impl(&self, state: &mut State) -> fmt::Result { let Self { + description, name, type_condition, directives, selection_set, } = self; + serialize_description(state, description)?; display!(state, "fragment {} on {}", name, type_condition)?; directives.serialize_impl(state)?; state.write(" ")?; @@ -581,11 +585,13 @@ impl Directive { impl VariableDefinition { fn serialize_impl(&self, state: &mut State) -> fmt::Result { let Self { + description, name, ty, default_value, directives, } = self; + serialize_description(state, description)?; state.write("$")?; state.write(name)?; state.write(": ")?; diff --git a/crates/apollo-compiler/src/executable/from_ast.rs b/crates/apollo-compiler/src/executable/from_ast.rs index 74ce323f1..5369077bb 100644 --- a/crates/apollo-compiler/src/executable/from_ast.rs +++ b/crates/apollo-compiler/src/executable/from_ast.rs @@ -140,6 +140,7 @@ impl Operation { let mut selection_set = SelectionSet::new(ty); selection_set.extend_from_ast(schema, errors, &ast.selection_set); Some(Self { + description: ast.description.clone(), operation_type: ast.operation_type, name: ast.name.clone(), variables: ast.variables.clone(), @@ -170,6 +171,7 @@ impl Fragment { let mut selection_set = SelectionSet::new(ast.type_condition.clone()); selection_set.extend_from_ast(schema, errors, &ast.selection_set); Some(Self { + description: ast.description.clone(), name: ast.name.clone(), directives: ast.directives.clone(), selection_set, diff --git a/crates/apollo-compiler/src/executable/mod.rs b/crates/apollo-compiler/src/executable/mod.rs index 36ff1b168..babe4fe0a 100644 --- a/crates/apollo-compiler/src/executable/mod.rs +++ b/crates/apollo-compiler/src/executable/mod.rs @@ -123,6 +123,7 @@ pub struct FieldSet { /// annotated with type information. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Operation { + pub description: Option>, pub operation_type: OperationType, pub name: Option, pub variables: Vec>, @@ -134,6 +135,7 @@ pub struct Operation { /// annotated with type information. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Fragment { + pub description: Option>, pub name: Name, pub directives: DirectiveList, pub selection_set: SelectionSet, diff --git a/crates/apollo-compiler/src/executable/serialize.rs b/crates/apollo-compiler/src/executable/serialize.rs index 84f9ad181..c43ee257f 100644 --- a/crates/apollo-compiler/src/executable/serialize.rs +++ b/crates/apollo-compiler/src/executable/serialize.rs @@ -28,6 +28,7 @@ impl ExecutableDocument { impl Operation { fn to_ast(&self, location: Option) -> ast::Definition { let def = ast::OperationDefinition { + description: self.description.clone(), operation_type: self.operation_type, name: self.name.clone(), variables: self.variables.clone(), @@ -45,6 +46,7 @@ impl Operation { impl Fragment { fn to_ast(&self, location: Option) -> ast::Definition { let def = ast::FragmentDefinition { + description: self.description.clone(), name: self.name.clone(), type_condition: self.selection_set.ty.clone(), directives: self.directives.clone(), diff --git a/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt b/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt index bff4e50a5..c3f7904b6 100644 --- a/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt +++ b/crates/apollo-compiler/test_data/ok/0001_annonymous_operation_definition.txt @@ -98,6 +98,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 1..31 @3 Operation { + description: None, operation_type: Query, name: None, variables: [], diff --git a/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt b/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt index 87d082ac8..d9d3425d3 100644 --- a/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt +++ b/crates/apollo-compiler/test_data/ok/0002_multiple_named_operation_definitions.txt @@ -133,6 +133,7 @@ ExecutableDocument { anonymous: None, named: { "getCatName": 0..41 @4 Operation { + description: None, operation_type: Query, name: Some( "getCatName", @@ -189,6 +190,7 @@ ExecutableDocument { }, }, "getOwnerName": 43..106 @4 Operation { + description: None, operation_type: Query, name: Some( "getOwnerName", diff --git a/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt b/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt index 499976190..9879d394c 100644 --- a/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt +++ b/crates/apollo-compiler/test_data/ok/0010_operation_with_defined_fields.txt @@ -252,6 +252,7 @@ ExecutableDocument { anonymous: None, named: { "getProduct": 0..68 @12 Operation { + description: None, operation_type: Query, name: Some( "getProduct", diff --git a/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt b/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt index 03e1f4085..82f8ac529 100644 --- a/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt +++ b/crates/apollo-compiler/test_data/ok/0011_fragment_spreads_in_fragment_definitions.txt @@ -122,6 +122,7 @@ ExecutableDocument { anonymous: None, named: { "IntrospectionQuery": 0..51 @13 Operation { + description: None, operation_type: Query, name: Some( "IntrospectionQuery", @@ -166,6 +167,7 @@ ExecutableDocument { }, fragments: { "Bar": 53..100 @13 Fragment { + description: None, name: "Bar", directives: [], selection_set: SelectionSet { @@ -203,6 +205,7 @@ ExecutableDocument { }, }, "Quux": 102..131 @13 Fragment { + description: None, name: "Quux", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt b/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt index 3baa1f761..9822ce9cb 100644 --- a/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt +++ b/crates/apollo-compiler/test_data/ok/0012_introspection_query.txt @@ -78,6 +78,7 @@ ExecutableDocument { anonymous: None, named: { "IntrospectionQuery": 0..271 @14 Operation { + description: None, operation_type: Query, name: Some( "IntrospectionQuery", @@ -418,6 +419,7 @@ ExecutableDocument { }, fragments: { "FullType": 272..723 @14 Fragment { + description: None, name: "FullType", directives: [], selection_set: SelectionSet { @@ -924,6 +926,7 @@ ExecutableDocument { }, }, "InputValue": 724..821 @14 Fragment { + description: None, name: "InputValue", directives: [], selection_set: SelectionSet { @@ -1026,6 +1029,7 @@ ExecutableDocument { }, }, "TypeRef": 822..1265 @14 Fragment { + description: None, name: "TypeRef", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt b/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt index 4dd78b27d..679634094 100644 --- a/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt +++ b/crates/apollo-compiler/test_data/ok/0013_operation_with_used_variable_in_fragment.txt @@ -210,12 +210,14 @@ ExecutableDocument { anonymous: None, named: { "ExampleQuery": 0..81 @15 Operation { + description: None, operation_type: Query, name: Some( "ExampleQuery", ), variables: [ 19..33 @15 VariableDefinition { + description: None, name: "variable", ty: 30..33 @15 Named( "Int", @@ -294,6 +296,7 @@ ExecutableDocument { }, fragments: { "subFrag": 83..163 @15 Fragment { + description: None, name: "subFrag", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt b/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt index 960cc6e56..8c43aa6cb 100644 --- a/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt +++ b/crates/apollo-compiler/test_data/ok/0016_same_variables_in_multiple_operations.txt @@ -146,12 +146,14 @@ ExecutableDocument { anonymous: None, named: { "A": 0..61 @18 Operation { + description: None, operation_type: Query, name: Some( "A", ), variables: [ 8..30 @18 VariableDefinition { + description: None, name: "atOtherHomes", ty: 23..30 @18 Named( "Boolean", @@ -174,12 +176,14 @@ ExecutableDocument { }, }, "B": 63..124 @18 Operation { + description: None, operation_type: Query, name: Some( "B", ), variables: [ 71..93 @18 VariableDefinition { + description: None, name: "atOtherHomes", ty: 86..93 @18 Named( "Boolean", @@ -205,6 +209,7 @@ ExecutableDocument { }, fragments: { "HouseTrainedFragment": 126..228 @18 Fragment { + description: None, name: "HouseTrainedFragment", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt b/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt index 4f4951906..dc89d6a79 100644 --- a/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt +++ b/crates/apollo-compiler/test_data/ok/0017_variables_are_input_types.txt @@ -225,12 +225,14 @@ ExecutableDocument { anonymous: None, named: { "takesBoolean": 0..106 @19 Operation { + description: None, operation_type: Query, name: Some( "takesBoolean", ), variables: [ 19..41 @19 VariableDefinition { + description: None, name: "atOtherHomes", ty: 34..41 @19 Named( "Boolean", @@ -307,12 +309,14 @@ ExecutableDocument { }, }, "takesComplexInput": 108..213 @19 Operation { + description: None, operation_type: Query, name: Some( "takesComplexInput", ), variables: [ 132..159 @19 VariableDefinition { + description: None, name: "complexInput", ty: 147..159 @19 Named( "ComplexInput", @@ -389,12 +393,14 @@ ExecutableDocument { }, }, "TakesListOfBooleanBang": 215..311 @19 Operation { + description: None, operation_type: Query, name: Some( "TakesListOfBooleanBang", ), variables: [ 244..265 @19 VariableDefinition { + description: None, name: "booleans", ty: 255..265 @19 List( NonNullNamed( diff --git a/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt b/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt index 695bb79b7..2ae0839e2 100644 --- a/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt +++ b/crates/apollo-compiler/test_data/ok/0018_non_clashing_names.txt @@ -117,6 +117,7 @@ ExecutableDocument { anonymous: None, named: { "A": 173..203 @20 Operation { + description: None, operation_type: Query, name: Some( "A", @@ -161,6 +162,7 @@ ExecutableDocument { }, fragments: { "A": 148..171 @20 Fragment { + description: None, name: "A", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt b/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt index 8c76ec718..de5c4af2a 100644 --- a/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt +++ b/crates/apollo-compiler/test_data/ok/0020_merge_identical_fields.txt @@ -111,6 +111,7 @@ ExecutableDocument { anonymous: None, named: { "queryPupper": 76..175 @22 Operation { + description: None, operation_type: Query, name: Some( "queryPupper", @@ -161,6 +162,7 @@ ExecutableDocument { }, fragments: { "mergeIdenticalFields": 177..231 @22 Fragment { + description: None, name: "mergeIdenticalFields", directives: [], selection_set: SelectionSet { @@ -212,6 +214,7 @@ ExecutableDocument { }, }, "mergeIdenticalAliasesAndFields": 233..319 @22 Fragment { + description: None, name: "mergeIdenticalAliasesAndFields", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt b/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt index 71c523bdc..9236c50c9 100644 --- a/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt +++ b/crates/apollo-compiler/test_data/ok/0021_merge_identical_fields_with_arguments.txt @@ -134,6 +134,7 @@ ExecutableDocument { anonymous: None, named: { "queryPupper": 126..204 @23 Operation { + description: None, operation_type: Query, name: Some( "queryPupper", @@ -175,12 +176,14 @@ ExecutableDocument { }, }, "queryPupperAgain": 206..316 @23 Operation { + description: None, operation_type: Query, name: Some( "queryPupperAgain", ), variables: [ 229..252 @23 VariableDefinition { + description: None, name: "dogCommand", ty: 242..252 @23 Named( "DogCommand", @@ -228,6 +231,7 @@ ExecutableDocument { }, fragments: { "mergeIdenticalFieldsWithIdenticalArgs": 318..445 @23 Fragment { + description: None, name: "mergeIdenticalFieldsWithIdenticalArgs", directives: [], selection_set: SelectionSet { @@ -313,6 +317,7 @@ ExecutableDocument { }, }, "mergeIdenticalFieldsWithIdenticalValues": 447..592 @23 Fragment { + description: None, name: "mergeIdenticalFieldsWithIdenticalValues", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt b/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt index 3be41e667..fa25edf16 100644 --- a/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt +++ b/crates/apollo-compiler/test_data/ok/0022_merge_differing_fields_and_args.txt @@ -307,6 +307,7 @@ ExecutableDocument { anonymous: None, named: { "barkVolume": 419..478 @24 Operation { + description: None, operation_type: Query, name: Some( "barkVolume", @@ -348,6 +349,7 @@ ExecutableDocument { }, }, "doesKnowCommand": 480..542 @24 Operation { + description: None, operation_type: Query, name: Some( "doesKnowCommand", @@ -389,6 +391,7 @@ ExecutableDocument { }, }, "isAtLocation": 544..607 @24 Operation { + description: None, operation_type: Query, name: Some( "isAtLocation", @@ -433,6 +436,7 @@ ExecutableDocument { }, fragments: { "safeDifferingFields": 609..732 @24 Fragment { + description: None, name: "safeDifferingFields", directives: [], selection_set: SelectionSet { @@ -514,6 +518,7 @@ ExecutableDocument { }, }, "safeDifferingArgs": 734..884 @24 Fragment { + description: None, name: "safeDifferingArgs", directives: [], selection_set: SelectionSet { @@ -625,6 +630,7 @@ ExecutableDocument { }, }, "safeDifferingArgOrder": 886..981 @24 Fragment { + description: None, name: "safeDifferingArgOrder", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt b/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt index aafcc5fcb..4f7486489 100644 --- a/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt +++ b/crates/apollo-compiler/test_data/ok/0024_used_variables_in_directives.txt @@ -111,10 +111,12 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 156..505 @25 Operation { + description: None, operation_type: Query, name: None, variables: [ 166..197 @25 VariableDefinition { + description: None, name: "fieldDirective", ty: 183..190 @25 Named( "Boolean", @@ -127,6 +129,7 @@ ExecutableDocument { directives: [], }, 201..232 @25 VariableDefinition { + description: None, name: "fragDirective", ty: 217..224 @25 Named( "Boolean", @@ -139,6 +142,7 @@ ExecutableDocument { directives: [], }, 236..269 @25 VariableDefinition { + description: None, name: "inlineDirective", ty: 254..261 @25 Named( "Boolean", @@ -151,6 +155,7 @@ ExecutableDocument { directives: [], }, 273..303 @25 VariableDefinition { + description: None, name: "argDirective", ty: 288..295 @25 Named( "Boolean", @@ -163,6 +168,7 @@ ExecutableDocument { directives: [], }, 307..342 @25 VariableDefinition { + description: None, name: "indirectDirective", ty: 327..334 @25 Named( "Boolean", @@ -299,6 +305,7 @@ ExecutableDocument { }, fragments: { "fragment": 79..154 @25 Fragment { + description: None, name: "fragment", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt b/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt index f651a2d0c..b03192c54 100644 --- a/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt +++ b/crates/apollo-compiler/test_data/ok/0025_unique_directives.txt @@ -95,6 +95,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 99..166 @26 Operation { + description: None, operation_type: Query, name: None, variables: [], diff --git a/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt b/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt index a4e1edf06..eee34426a 100644 --- a/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt +++ b/crates/apollo-compiler/test_data/ok/0026_type_introspection.txt @@ -122,6 +122,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 108..213 @27 Operation { + description: None, operation_type: Query, name: None, variables: [], diff --git a/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt b/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt index 20f5211d1..43cd681de 100644 --- a/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt +++ b/crates/apollo-compiler/test_data/ok/0027_typename_introspection_in_object.txt @@ -122,6 +122,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 108..135 @28 Operation { + description: None, operation_type: Query, name: None, variables: [], diff --git a/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt b/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt index c8331cb1c..d3098896d 100644 --- a/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt +++ b/crates/apollo-compiler/test_data/ok/0028_typename_introspection_in_union.txt @@ -162,6 +162,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 173..292 @29 Operation { + description: None, operation_type: Query, name: None, variables: [], diff --git a/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt b/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt index 7d57527f3..1e88a4ce6 100644 --- a/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt +++ b/crates/apollo-compiler/test_data/ok/0029_used_variable_in_list_and_input.txt @@ -150,10 +150,12 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 156..302 @30 Operation { + description: None, operation_type: Query, name: None, variables: [ 163..186 @30 VariableDefinition { + description: None, name: "attributeName", ty: 179..186 @30 NonNullNamed( "String", @@ -162,6 +164,7 @@ ExecutableDocument { directives: [], }, 188..195 @30 VariableDefinition { + description: None, name: "v", ty: 192..195 @30 Named( "Int", diff --git a/crates/apollo-compiler/test_data/ok/0031_fragment_spread_possible.txt b/crates/apollo-compiler/test_data/ok/0031_fragment_spread_possible.txt index 6847ae9d9..0fa2600ec 100644 --- a/crates/apollo-compiler/test_data/ok/0031_fragment_spread_possible.txt +++ b/crates/apollo-compiler/test_data/ok/0031_fragment_spread_possible.txt @@ -353,6 +353,7 @@ ExecutableDocument { anonymous: None, named: { "UseAllFragments": 1759..2068 @32 Operation { + description: None, operation_type: Query, name: Some( "UseAllFragments", @@ -501,6 +502,7 @@ ExecutableDocument { }, fragments: { "dogFragment": 327..392 @32 Fragment { + description: None, name: "dogFragment", directives: [], selection_set: SelectionSet { @@ -544,6 +546,7 @@ ExecutableDocument { }, }, "petNameFragment": 471..513 @32 Fragment { + description: None, name: "petNameFragment", directives: [], selection_set: SelectionSet { @@ -574,6 +577,7 @@ ExecutableDocument { }, }, "interfaceWithinObjectFragment": 515..585 @32 Fragment { + description: None, name: "interfaceWithinObjectFragment", directives: [], selection_set: SelectionSet { @@ -589,6 +593,7 @@ ExecutableDocument { }, }, "catOrDogNameFragment": 587..666 @32 Fragment { + description: None, name: "catOrDogNameFragment", directives: [], selection_set: SelectionSet { @@ -632,6 +637,7 @@ ExecutableDocument { }, }, "unionWithObjectFragment": 668..737 @32 Fragment { + description: None, name: "unionWithObjectFragment", directives: [], selection_set: SelectionSet { @@ -647,6 +653,7 @@ ExecutableDocument { }, }, "petFragment": 816..888 @32 Fragment { + description: None, name: "petFragment", directives: [], selection_set: SelectionSet { @@ -711,6 +718,7 @@ ExecutableDocument { }, }, "catOrDogFragment": 890..965 @32 Fragment { + description: None, name: "catOrDogFragment", directives: [], selection_set: SelectionSet { @@ -754,6 +762,7 @@ ExecutableDocument { }, }, "unionWithInterface": 1046..1108 @32 Fragment { + description: None, name: "unionWithInterface", directives: [], selection_set: SelectionSet { @@ -769,6 +778,7 @@ ExecutableDocument { }, }, "dogOrHumanFragment": 1110..1189 @32 Fragment { + description: None, name: "dogOrHumanFragment", directives: [], selection_set: SelectionSet { @@ -812,6 +822,7 @@ ExecutableDocument { }, }, "interfaceWithInterface": 1554..1619 @32 Fragment { + description: None, name: "interfaceWithInterface", directives: [], selection_set: SelectionSet { @@ -827,6 +838,7 @@ ExecutableDocument { }, }, "resourceFragment": 1621..1668 @32 Fragment { + description: None, name: "resourceFragment", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0032_valid_of_correct_type.txt b/crates/apollo-compiler/test_data/ok/0032_valid_of_correct_type.txt index 9f3c46567..331e4c8f5 100644 --- a/crates/apollo-compiler/test_data/ok/0032_valid_of_correct_type.txt +++ b/crates/apollo-compiler/test_data/ok/0032_valid_of_correct_type.txt @@ -894,6 +894,7 @@ ExecutableDocument { anonymous: None, named: { "goodIntValue": 1526..1599 @33 Operation { + description: None, operation_type: Query, name: Some( "goodIntValue", @@ -967,6 +968,7 @@ ExecutableDocument { }, }, "goodNegativeIntValue": 1601..1682 @33 Operation { + description: None, operation_type: Query, name: Some( "goodNegativeIntValue", @@ -1040,6 +1042,7 @@ ExecutableDocument { }, }, "goodBooleanValue": 1684..1772 @33 Operation { + description: None, operation_type: Query, name: Some( "goodBooleanValue", @@ -1113,6 +1116,7 @@ ExecutableDocument { }, }, "goodStringValue": 1774..1860 @33 Operation { + description: None, operation_type: Query, name: Some( "goodStringValue", @@ -1186,6 +1190,7 @@ ExecutableDocument { }, }, "goodFloatValue": 1862..1943 @33 Operation { + description: None, operation_type: Query, name: Some( "goodFloatValue", @@ -1259,6 +1264,7 @@ ExecutableDocument { }, }, "goodNegativeFloatValue": 1945..2035 @33 Operation { + description: None, operation_type: Query, name: Some( "goodNegativeFloatValue", @@ -1332,6 +1338,7 @@ ExecutableDocument { }, }, "intIntoFloat": 2037..2114 @33 Operation { + description: None, operation_type: Query, name: Some( "intIntoFloat", @@ -1405,6 +1412,7 @@ ExecutableDocument { }, }, "intIntoID": 2116..2184 @33 Operation { + description: None, operation_type: Query, name: Some( "intIntoID", @@ -1478,6 +1486,7 @@ ExecutableDocument { }, }, "stringIntoID": 2186..2270 @33 Operation { + description: None, operation_type: Query, name: Some( "stringIntoID", @@ -1551,6 +1560,7 @@ ExecutableDocument { }, }, "goodEnumValue": 2272..2344 @33 Operation { + description: None, operation_type: Query, name: Some( "goodEnumValue", @@ -1624,6 +1634,7 @@ ExecutableDocument { }, }, "enumWithUndefinedValue": 2346..2437 @33 Operation { + description: None, operation_type: Query, name: Some( "enumWithUndefinedValue", @@ -1697,6 +1708,7 @@ ExecutableDocument { }, }, "enumWithNullValue": 2439..2522 @33 Operation { + description: None, operation_type: Query, name: Some( "enumWithNullValue", @@ -1768,6 +1780,7 @@ ExecutableDocument { }, }, "nullIntoNullableType": 2524..2608 @33 Operation { + description: None, operation_type: Query, name: Some( "nullIntoNullableType", @@ -1839,6 +1852,7 @@ ExecutableDocument { }, }, "goodListValue": 2610..2717 @33 Operation { + description: None, operation_type: Query, name: Some( "goodListValue", @@ -1922,6 +1936,7 @@ ExecutableDocument { }, }, "emptyListValue": 2719..2809 @33 Operation { + description: None, operation_type: Query, name: Some( "emptyListValue", @@ -1997,6 +2012,7 @@ ExecutableDocument { }, }, "nullListValue": 2811..2902 @33 Operation { + description: None, operation_type: Query, name: Some( "nullListValue", @@ -2070,6 +2086,7 @@ ExecutableDocument { }, }, "singleValueIntoList": 2904..3002 @33 Operation { + description: None, operation_type: Query, name: Some( "singleValueIntoList", @@ -2145,6 +2162,7 @@ ExecutableDocument { }, }, "argOnOptionalArg": 3031..3108 @33 Operation { + description: None, operation_type: Query, name: Some( "argOnOptionalArg", @@ -2222,6 +2240,7 @@ ExecutableDocument { }, }, "noArgOnOptionalArg": 3110..3169 @33 Operation { + description: None, operation_type: Query, name: Some( "noArgOnOptionalArg", @@ -2292,6 +2311,7 @@ ExecutableDocument { }, }, "multipleArgs": 3171..3252 @33 Operation { + description: None, operation_type: Query, name: Some( "multipleArgs", @@ -2380,6 +2400,7 @@ ExecutableDocument { }, }, "multiplArgsReverseOrder": 3254..3346 @33 Operation { + description: None, operation_type: Query, name: Some( "multiplArgsReverseOrder", @@ -2468,6 +2489,7 @@ ExecutableDocument { }, }, "noArgsOnMultipleOptional": 3348..3423 @33 Operation { + description: None, operation_type: Query, name: Some( "noArgsOnMultipleOptional", @@ -2551,6 +2573,7 @@ ExecutableDocument { }, }, "oneArgOnMultipleOptional": 3425..3509 @33 Operation { + description: None, operation_type: Query, name: Some( "oneArgOnMultipleOptional", @@ -2641,6 +2664,7 @@ ExecutableDocument { }, }, "secondArgOnMultipleOptional": 3511..3598 @33 Operation { + description: None, operation_type: Query, name: Some( "secondArgOnMultipleOptional", @@ -2731,6 +2755,7 @@ ExecutableDocument { }, }, "multipleRequiredArgsOnMixedList": 3600..3705 @33 Operation { + description: None, operation_type: Query, name: Some( "multipleRequiredArgsOnMixedList", @@ -2845,6 +2870,7 @@ ExecutableDocument { }, }, "multipleRequiredAndOneOptionalArgOnMixedList": 3707..3834 @33 Operation { + description: None, operation_type: Query, name: Some( "multipleRequiredAndOneOptionalArgOnMixedList", @@ -2965,6 +2991,7 @@ ExecutableDocument { }, }, "AllRequiredAndOptionalArgsOnMixedList": 3836..3965 @33 Operation { + description: None, operation_type: Query, name: Some( "AllRequiredAndOptionalArgsOnMixedList", @@ -3091,6 +3118,7 @@ ExecutableDocument { }, }, "optionalArgDespiteRequiredFieldInType": 3994..4085 @33 Operation { + description: None, operation_type: Query, name: Some( "optionalArgDespiteRequiredFieldInType", @@ -3157,6 +3185,7 @@ ExecutableDocument { }, }, "partialObjectOnlyRequired": 4087..4203 @33 Operation { + description: None, operation_type: Query, name: Some( "partialObjectOnlyRequired", @@ -3237,6 +3266,7 @@ ExecutableDocument { }, }, "partialObjectRequiredFieldCanBeFalse": 4205..4333 @33 Operation { + description: None, operation_type: Query, name: Some( "partialObjectRequiredFieldCanBeFalse", @@ -3317,6 +3347,7 @@ ExecutableDocument { }, }, "partialObjectIncludingRequired": 4335..4469 @33 Operation { + description: None, operation_type: Query, name: Some( "partialObjectIncludingRequired", @@ -3403,6 +3434,7 @@ ExecutableDocument { }, }, "fullObject": 4471..4693 @33 Operation { + description: None, operation_type: Query, name: Some( "fullObject", @@ -3514,6 +3546,7 @@ ExecutableDocument { }, }, "fullObjectWithFieldsInDifferentOrder": 4695..4944 @33 Operation { + description: None, operation_type: Query, name: Some( "fullObjectWithFieldsInDifferentOrder", @@ -3625,6 +3658,7 @@ ExecutableDocument { }, }, "withDirectivesOfValidTypes": 4946..5062 @33 Operation { + description: None, operation_type: Query, name: Some( "withDirectivesOfValidTypes", @@ -3778,12 +3812,14 @@ ExecutableDocument { }, }, "withDefaultValues": 5091..5337 @33 Operation { + description: None, operation_type: Query, name: Some( "withDefaultValues", ), variables: [ 5118..5129 @33 VariableDefinition { + description: None, name: "a", ty: 5122..5125 @33 Named( "Int", @@ -3796,6 +3832,7 @@ ExecutableDocument { directives: [], }, 5133..5150 @33 VariableDefinition { + description: None, name: "b", ty: 5137..5143 @33 Named( "String", @@ -3808,6 +3845,7 @@ ExecutableDocument { directives: [], }, 5154..5209 @33 VariableDefinition { + description: None, name: "c", ty: 5158..5170 @33 Named( "ComplexInput", @@ -3977,12 +4015,14 @@ ExecutableDocument { }, }, "variablesWithDefaultNullValues": 5339..5605 @33 Operation { + description: None, operation_type: Query, name: Some( "variablesWithDefaultNullValues", ), variables: [ 5379..5393 @33 VariableDefinition { + description: None, name: "a", ty: 5383..5386 @33 Named( "Int", @@ -3993,6 +4033,7 @@ ExecutableDocument { directives: [], }, 5397..5414 @33 VariableDefinition { + description: None, name: "b", ty: 5401..5407 @33 Named( "String", @@ -4003,6 +4044,7 @@ ExecutableDocument { directives: [], }, 5418..5476 @33 VariableDefinition { + description: None, name: "c", ty: 5422..5434 @33 Named( "ComplexInput", @@ -4170,6 +4212,7 @@ ExecutableDocument { }, }, "customScalarWithStringValue": 5624..5726 @33 Operation { + description: None, operation_type: Query, name: Some( "customScalarWithStringValue", @@ -4243,6 +4286,7 @@ ExecutableDocument { }, }, "customScalarWithIntValue": 5728..5820 @33 Operation { + description: None, operation_type: Query, name: Some( "customScalarWithIntValue", @@ -4316,6 +4360,7 @@ ExecutableDocument { }, }, "customScalarWithBooleanValue": 5822..5921 @33 Operation { + description: None, operation_type: Query, name: Some( "customScalarWithBooleanValue", @@ -4389,6 +4434,7 @@ ExecutableDocument { }, }, "customScalarWithFloatValue": 5923..6019 @33 Operation { + description: None, operation_type: Query, name: Some( "customScalarWithFloatValue", @@ -4462,12 +4508,14 @@ ExecutableDocument { }, }, "customScalarWithVariableValue": 6021..6146 @33 Operation { + description: None, operation_type: Query, name: Some( "customScalarWithVariableValue", ), variables: [ 6057..6076 @33 VariableDefinition { + description: None, name: "custom", ty: 6066..6072 @33 Named( "Custom", @@ -4548,6 +4596,7 @@ ExecutableDocument { }, }, "customScalarWithArbitraryInputObject": 6148..6265 @33 Operation { + description: None, operation_type: Query, name: Some( "customScalarWithArbitraryInputObject", @@ -4628,6 +4677,7 @@ ExecutableDocument { }, }, "customScalarWithListValue": 6267..6368 @33 Operation { + description: None, operation_type: Query, name: Some( "customScalarWithListValue", diff --git a/crates/apollo-compiler/test_data/ok/0033_valid_variable_usage.txt b/crates/apollo-compiler/test_data/ok/0033_valid_variable_usage.txt index b4027ad2a..57541337e 100644 --- a/crates/apollo-compiler/test_data/ok/0033_valid_variable_usage.txt +++ b/crates/apollo-compiler/test_data/ok/0033_valid_variable_usage.txt @@ -160,12 +160,14 @@ ExecutableDocument { anonymous: None, named: { "nullableStringArg": 0..296 @34 Operation { + description: None, operation_type: Query, name: Some( "nullableStringArg", ), variables: [ 24..48 @34 VariableDefinition { + description: None, name: "nonNullableVar", ty: 41..48 @34 NonNullNamed( "String", @@ -174,6 +176,7 @@ ExecutableDocument { directives: [], }, 50..78 @34 VariableDefinition { + description: None, name: "nonNullableList", ty: 68..78 @34 NonNullList( NonNullNamed( @@ -184,6 +187,7 @@ ExecutableDocument { directives: [], }, 80..111 @34 VariableDefinition { + description: None, name: "nonNullableListList", ty: 102..111 @34 List( NonNullList( diff --git a/crates/apollo-compiler/test_data/ok/0038_argument_default.txt b/crates/apollo-compiler/test_data/ok/0038_argument_default.txt index c1cc70b94..de3b65dcb 100644 --- a/crates/apollo-compiler/test_data/ok/0038_argument_default.txt +++ b/crates/apollo-compiler/test_data/ok/0038_argument_default.txt @@ -124,6 +124,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 149..185 @39 Operation { + description: None, operation_type: Query, name: None, variables: [], diff --git a/crates/apollo-compiler/test_data/ok/0040_field_merging_issue_755.txt b/crates/apollo-compiler/test_data/ok/0040_field_merging_issue_755.txt index 78526ef57..2de05085f 100644 --- a/crates/apollo-compiler/test_data/ok/0040_field_merging_issue_755.txt +++ b/crates/apollo-compiler/test_data/ok/0040_field_merging_issue_755.txt @@ -135,6 +135,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 592..643 @41 Operation { + description: None, operation_type: Query, name: None, variables: [], @@ -178,6 +179,7 @@ ExecutableDocument { }, fragments: { "topLevelFragment": 314..446 @41 Fragment { + description: None, name: "topLevelFragment", directives: [], selection_set: SelectionSet { @@ -244,6 +246,7 @@ ExecutableDocument { }, }, "collidingTopLevelFragment": 447..529 @41 Fragment { + description: None, name: "collidingTopLevelFragment", directives: [], selection_set: SelectionSet { @@ -298,6 +301,7 @@ ExecutableDocument { }, }, "subselectionFragment": 530..591 @41 Fragment { + description: None, name: "subselectionFragment", directives: [], selection_set: SelectionSet { diff --git a/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.txt b/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.txt index 2a31b08f8..ab1d4c82e 100644 --- a/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.txt +++ b/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.txt @@ -103,6 +103,7 @@ ExecutableDocument { operations: OperationMap { anonymous: Some( 89..141 @42 Operation { + description: None, operation_type: Query, name: None, variables: [], diff --git a/crates/apollo-compiler/test_data/ok/0042_used_variable_in_operation_directive.txt b/crates/apollo-compiler/test_data/ok/0042_used_variable_in_operation_directive.txt index 345d516d6..65cc17236 100644 --- a/crates/apollo-compiler/test_data/ok/0042_used_variable_in_operation_directive.txt +++ b/crates/apollo-compiler/test_data/ok/0042_used_variable_in_operation_directive.txt @@ -172,12 +172,14 @@ ExecutableDocument { anonymous: None, named: { "Q": 207..263 @43 Operation { + description: None, operation_type: Query, name: Some( "Q", ), variables: [ 216..224 @43 VariableDefinition { + description: None, name: "a", ty: 220..224 @43 NonNullNamed( "Int", @@ -186,6 +188,7 @@ ExecutableDocument { directives: [], }, 226..237 @43 VariableDefinition { + description: None, name: "f", ty: 230..237 @43 Named( "Boolean", @@ -241,12 +244,14 @@ ExecutableDocument { }, }, "M": 264..305 @43 Operation { + description: None, operation_type: Mutation, name: Some( "M", ), variables: [ 276..284 @43 VariableDefinition { + description: None, name: "b", ty: 280..284 @43 NonNullNamed( "Int", @@ -296,12 +301,14 @@ ExecutableDocument { }, }, "S": 306..351 @43 Operation { + description: None, operation_type: Subscription, name: Some( "S", ), variables: [ 322..330 @43 VariableDefinition { + description: None, name: "c", ty: 326..330 @43 NonNullNamed( "Int", @@ -354,6 +361,7 @@ ExecutableDocument { }, fragments: { "f": 353..392 @43 Fragment { + description: None, name: "f", directives: [ 373..382 @43 Directive { diff --git a/crates/apollo-compiler/test_data/ok/0116_interface_without_implementations.txt b/crates/apollo-compiler/test_data/ok/0116_interface_without_implementations.txt index 7336d7d8c..9dd9f8256 100644 --- a/crates/apollo-compiler/test_data/ok/0116_interface_without_implementations.txt +++ b/crates/apollo-compiler/test_data/ok/0116_interface_without_implementations.txt @@ -100,6 +100,7 @@ ExecutableDocument { anonymous: None, named: { "SelectDirectly": 61..102 @45 Operation { + description: None, operation_type: Query, name: Some( "SelectDirectly", @@ -156,6 +157,7 @@ ExecutableDocument { }, }, "UsingInlineFragment": 104..172 @45 Operation { + description: None, operation_type: Query, name: Some( "UsingInlineFragment", diff --git a/crates/apollo-compiler/test_data/ok/0117_subscription_conditions_not_at_root.txt b/crates/apollo-compiler/test_data/ok/0117_subscription_conditions_not_at_root.txt index 5824191ac..4df78509b 100644 --- a/crates/apollo-compiler/test_data/ok/0117_subscription_conditions_not_at_root.txt +++ b/crates/apollo-compiler/test_data/ok/0117_subscription_conditions_not_at_root.txt @@ -150,12 +150,14 @@ ExecutableDocument { anonymous: None, named: { "ConditionalSub": 0..202 @46 Operation { + description: None, operation_type: Subscription, name: Some( "ConditionalSub", ), variables: [ 28..59 @46 VariableDefinition { + description: None, name: "includeContent", ty: 45..52 @46 Named( "Boolean", @@ -168,6 +170,7 @@ ExecutableDocument { directives: [], }, 61..83 @46 VariableDefinition { + description: None, name: "small", ty: 69..76 @46 Named( "Boolean", diff --git a/crates/apollo-compiler/test_data/ok/0118_directive_with_nested_input_types.txt b/crates/apollo-compiler/test_data/ok/0118_directive_with_nested_input_types.txt index ac643af0c..45629e05b 100644 --- a/crates/apollo-compiler/test_data/ok/0118_directive_with_nested_input_types.txt +++ b/crates/apollo-compiler/test_data/ok/0118_directive_with_nested_input_types.txt @@ -165,6 +165,7 @@ ExecutableDocument { anonymous: None, named: { "myQuery": 208..231 @47 Operation { + description: None, operation_type: Query, name: Some( "myQuery", diff --git a/crates/apollo-compiler/test_data/ok/0119_directive_with_argument_type_collisions.txt b/crates/apollo-compiler/test_data/ok/0119_directive_with_argument_type_collisions.txt index aa297d43f..7958031a2 100644 --- a/crates/apollo-compiler/test_data/ok/0119_directive_with_argument_type_collisions.txt +++ b/crates/apollo-compiler/test_data/ok/0119_directive_with_argument_type_collisions.txt @@ -165,6 +165,7 @@ ExecutableDocument { anonymous: None, named: { "myQuery": 193..216 @48 Operation { + description: None, operation_type: Query, name: Some( "myQuery", diff --git a/crates/apollo-parser/src/cst/generated/nodes.rs b/crates/apollo-parser/src/cst/generated/nodes.rs index 491f0ee52..a59058c90 100644 --- a/crates/apollo-parser/src/cst/generated/nodes.rs +++ b/crates/apollo-parser/src/cst/generated/nodes.rs @@ -4,8 +4,8 @@ use crate::cst::support; use crate::cst::CstChildren; use crate::cst::CstNode; -use crate::SyntaxKind; use crate::SyntaxKind::*; +use crate::SyntaxKind::{self}; use crate::SyntaxNode; use crate::SyntaxToken; use crate::S; @@ -32,6 +32,9 @@ pub struct OperationDefinition { pub(crate) syntax: SyntaxNode, } impl OperationDefinition { + pub fn description(&self) -> Option { + support::child(&self.syntax) + } pub fn operation_type(&self) -> Option { support::child(&self.syntax) } @@ -53,6 +56,9 @@ pub struct FragmentDefinition { pub(crate) syntax: SyntaxNode, } impl FragmentDefinition { + pub fn description(&self) -> Option { + support::child(&self.syntax) + } pub fn fragment_token(&self) -> Option { support::token(&self.syntax, S![fragment]) } @@ -406,6 +412,15 @@ impl InputObjectTypeExtension { } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Description { + pub(crate) syntax: SyntaxNode, +} +impl Description { + pub fn string_value(&self) -> Option { + support::child(&self.syntax) + } +} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct OperationType { pub(crate) syntax: SyntaxNode, } @@ -700,6 +715,9 @@ pub struct VariableDefinition { pub(crate) syntax: SyntaxNode, } impl VariableDefinition { + pub fn description(&self) -> Option { + support::child(&self.syntax) + } pub fn variable(&self) -> Option { support::child(&self.syntax) } @@ -774,15 +792,6 @@ impl Directive { } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Description { - pub(crate) syntax: SyntaxNode, -} -impl Description { - pub fn string_value(&self) -> Option { - support::child(&self.syntax) - } -} -#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RootOperationTypeDefinition { pub(crate) syntax: SyntaxNode, } @@ -1351,6 +1360,21 @@ impl CstNode for InputObjectTypeExtension { &self.syntax } } +impl CstNode for Description { + fn can_cast(kind: SyntaxKind) -> bool { + kind == DESCRIPTION + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} impl CstNode for OperationType { fn can_cast(kind: SyntaxKind) -> bool { kind == OPERATION_TYPE @@ -1771,21 +1795,6 @@ impl CstNode for Directive { &self.syntax } } -impl CstNode for Description { - fn can_cast(kind: SyntaxKind) -> bool { - kind == DESCRIPTION - } - fn cast(syntax: SyntaxNode) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - fn syntax(&self) -> &SyntaxNode { - &self.syntax - } -} impl CstNode for RootOperationTypeDefinition { fn can_cast(kind: SyntaxKind) -> bool { kind == ROOT_OPERATION_TYPE_DEFINITION diff --git a/crates/apollo-parser/src/parser/grammar/fragment.rs b/crates/apollo-parser/src/parser/grammar/fragment.rs index bfc532984..3e562a5dc 100644 --- a/crates/apollo-parser/src/parser/grammar/fragment.rs +++ b/crates/apollo-parser/src/parser/grammar/fragment.rs @@ -1,3 +1,4 @@ +use crate::parser::grammar::description; use crate::parser::grammar::directive; use crate::parser::grammar::name; use crate::parser::grammar::selection; @@ -9,12 +10,18 @@ use crate::TokenKind; use crate::S; use crate::T; -/// See: https://spec.graphql.org/October2021/#FragmentDefinition +/// See: https://spec.graphql.org/September2025/#sec-Language.Fragments /// /// *FragmentDefinition*: -/// **fragment** FragmentName TypeCondition Directives? SelectionSet +/// Description? **fragment** FragmentName TypeCondition Directives? SelectionSet pub(crate) fn fragment_definition(p: &mut Parser) { let _g = p.start_node(SyntaxKind::FRAGMENT_DEFINITION); + + // Check for optional description + if let Some(TokenKind::StringValue) = p.peek() { + description::description(p); + } + p.bump(SyntaxKind::fragment_KW); fragment_name(p); @@ -30,7 +37,7 @@ pub(crate) fn fragment_definition(p: &mut Parser) { } } -/// See: https://spec.graphql.org/October2021/#FragmentName +/// See: https://spec.graphql.org/September2025/#sec-Language.Fragments /// /// *FragmentName*: /// Name *but not* **on** @@ -47,7 +54,7 @@ pub(crate) fn fragment_name(p: &mut Parser) { } } -/// See: https://spec.graphql.org/October2021/#TypeCondition +/// See: https://spec.graphql.org/September2025/#sec-Language.Fragments /// /// *TypeCondition*: /// **on** NamedType @@ -71,7 +78,7 @@ pub(crate) fn type_condition(p: &mut Parser) { } } -/// See: https://spec.graphql.org/October2021/#InlineFragment +/// See: https://spec.graphql.org/September2025/#sec-Language.Fragments /// /// *InlineFragment*: /// **...** TypeCondition? Directives? SelectionSet @@ -93,7 +100,7 @@ pub(crate) fn inline_fragment(p: &mut Parser) { } } -/// See: https://spec.graphql.org/October2021/#FragmentSpread +/// See: https://spec.graphql.org/September2025/#sec-Language.Fragments /// /// *FragmentSpread*: /// **...** FragmentName Directives? diff --git a/crates/apollo-parser/src/parser/grammar/operation.rs b/crates/apollo-parser/src/parser/grammar/operation.rs index 0b6cf98c9..6c03e16fb 100644 --- a/crates/apollo-parser/src/parser/grammar/operation.rs +++ b/crates/apollo-parser/src/parser/grammar/operation.rs @@ -1,3 +1,4 @@ +use crate::parser::grammar::description; use crate::parser::grammar::directive; use crate::parser::grammar::name; use crate::parser::grammar::selection; @@ -8,13 +9,43 @@ use crate::SyntaxKind; use crate::TokenKind; use crate::T; -/// See: https://spec.graphql.org/October2021/#OperationDefinition +/// See: https://spec.graphql.org/September2025/#sec-Language.Operations /// /// *OperationDefinition*: -/// OperationType Name? VariableDefinitions? Directives? SelectionSet +/// Description? OperationType Name? VariableDefinitions? Directives? SelectionSet /// SelectionSet pub(crate) fn operation_definition(p: &mut Parser) { match p.peek() { + Some(TokenKind::StringValue) => { + // Description found - must be full operation definition, not shorthand + let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION); + + description::description(p); + + // After description, we must have an operation type + if let Some(TokenKind::Name) = p.peek() { + operation_type(p); + } else { + return p.err_and_pop("expected an Operation Type after description"); + } + + if let Some(TokenKind::Name) = p.peek() { + name::name(p); + } + + if let Some(T!['(']) = p.peek() { + variable::variable_definitions(p) + } + + if let Some(T![@]) = p.peek() { + directive::directives(p, Constness::NotConst); + } + + match p.peek() { + Some(T!['{']) => selection::selection_set(p), + _ => p.err_and_pop("expected a Selection Set"), + } + } Some(TokenKind::Name) => { let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION); @@ -46,7 +77,7 @@ pub(crate) fn operation_definition(p: &mut Parser) { } } -/// See: https://spec.graphql.org/October2021/#OperationType +/// See: https://spec.graphql.org/September2025/#sec-Language.Operations /// /// *OperationType*: one of /// **query** **mutation** **subscription** @@ -66,15 +97,25 @@ pub(crate) fn operation_type(p: &mut Parser) { mod test { use crate::Parser; - // NOTE @lrlna: related PR to the spec to avoid this issue: - // https://github.com/graphql/graphql-spec/pull/892 + // NOTE @lrlna: Descriptions on operations are now supported in September 2025 spec + // https://github.com/graphql/graphql-spec/pull/1170 #[test] - fn it_continues_parsing_when_operation_definition_starts_with_description() { - let input = "\"description\"{}"; + fn it_parses_operation_definition_with_description() { + let input = "\"A test query\" query Test { field }"; let parser = Parser::new(input); let cst = parser.parse(); - assert_eq!(cst.errors().len(), 2); + assert_eq!(cst.errors().len(), 0); assert_eq!(cst.document().definitions().count(), 1); } + + #[test] + fn it_errors_on_shorthand_query_with_description() { + let input = "\"description\"{}"; + let parser = Parser::new(input); + let cst = parser.parse(); + + // Should error because descriptions are not allowed on shorthand queries + assert!(cst.errors().len() > 0); + } } diff --git a/crates/apollo-parser/src/parser/grammar/variable.rs b/crates/apollo-parser/src/parser/grammar/variable.rs index 55209605c..804af326c 100644 --- a/crates/apollo-parser/src/parser/grammar/variable.rs +++ b/crates/apollo-parser/src/parser/grammar/variable.rs @@ -1,3 +1,4 @@ +use crate::parser::grammar::description; use crate::parser::grammar::directive; use crate::parser::grammar::name; use crate::parser::grammar::ty; @@ -9,7 +10,7 @@ use crate::TokenKind; use crate::S; use crate::T; -/// See: https://spec.graphql.org/October2021/#VariableDefinitions +/// See: https://spec.graphql.org/September2025/#sec-Language.Variables /// /// *VariableDefinitions*: /// **(** VariableDefinition* **)** @@ -17,22 +18,33 @@ pub(crate) fn variable_definitions(p: &mut Parser) { let _g = p.start_node(SyntaxKind::VARIABLE_DEFINITIONS); p.bump(S!['(']); - if let Some(T![$]) = p.peek() { + // Variable definitions can start with a description (string) or $ (variable) + if let Some(TokenKind::StringValue | T![$]) = p.peek() { variable_definition(p); } else { p.err("expected a Variable Definition") } - p.peek_while_kind(T![$], variable_definition); + + // Continue parsing while we see descriptions or variables + while let Some(TokenKind::StringValue | T![$]) = p.peek() { + variable_definition(p); + } p.expect(T![')'], S![')']); } -/// See: https://spec.graphql.org/October2021/#VariableDefinition +/// See: https://spec.graphql.org/September2025/#sec-Language.Variables /// /// *VariableDefinition*: -/// Variable **:** Type DefaultValue? Directives[Const]? +/// Description? Variable **:** Type DefaultValue? Directives[Const]? pub(crate) fn variable_definition(p: &mut Parser) { let _guard = p.start_node(SyntaxKind::VARIABLE_DEFINITION); + + // Check for optional description + if let Some(TokenKind::StringValue) = p.peek() { + description::description(p); + } + variable(p); if let Some(T![:]) = p.peek() { @@ -53,7 +65,7 @@ pub(crate) fn variable_definition(p: &mut Parser) { } } -/// See: https://spec.graphql.org/October2021/#Variable +/// See: https://spec.graphql.org/September2025/#sec-Language.Variables /// /// *Variable*: /// **$** Name diff --git a/crates/apollo-parser/test_data/parser/err/0030_operation_definition_with_description.txt b/crates/apollo-parser/test_data/parser/err/0030_operation_definition_with_description.txt index b5fc3ff0b..89032db3e 100644 --- a/crates/apollo-parser/test_data/parser/err/0030_operation_definition_with_description.txt +++ b/crates/apollo-parser/test_data/parser/err/0030_operation_definition_with_description.txt @@ -1,7 +1,9 @@ - DOCUMENT@0..108 - - ERROR@0..93 "\"after this PR this should not be an issue: https://github.com/graphql/graphql-spec/pull/892\"" - - WHITESPACE@93..94 "\n" - - OPERATION_DEFINITION@94..108 + - OPERATION_DEFINITION@0..108 + - DESCRIPTION@0..93 + - STRING_VALUE@0..93 + - STRING@0..93 "\"after this PR this should not be an issue: https://github.com/graphql/graphql-spec/pull/892\"" + - WHITESPACE@93..94 "\n" - OPERATION_TYPE@94..99 - query_KW@94..99 "query" - WHITESPACE@99..100 " " @@ -11,6 +13,5 @@ - SELECTION_SET@106..108 - L_CURLY@106..107 "{" - R_CURLY@107..108 "}" -- ERROR@0:93 "expected an Operation Type or a Selection Set" "after this PR this should not be an issue: https://github.com/graphql/graphql-spec/pull/892" - ERROR@107:108 "expected at least one Selection in Selection Set" } recursion limit: 500, high: 1 \ No newline at end of file diff --git a/crates/apollo-parser/test_data/parser/ok/0070_operation_definition_with_description.graphql b/crates/apollo-parser/test_data/parser/ok/0070_operation_definition_with_description.graphql new file mode 100644 index 000000000..c2ca87cef --- /dev/null +++ b/crates/apollo-parser/test_data/parser/ok/0070_operation_definition_with_description.graphql @@ -0,0 +1,3 @@ +"Operation with description - now supported in September 2025 spec" +query TestQuery { field } + diff --git a/crates/apollo-parser/test_data/parser/ok/0070_operation_definition_with_description.txt b/crates/apollo-parser/test_data/parser/ok/0070_operation_definition_with_description.txt new file mode 100644 index 000000000..3db4a01ff --- /dev/null +++ b/crates/apollo-parser/test_data/parser/ok/0070_operation_definition_with_description.txt @@ -0,0 +1,22 @@ +- DOCUMENT@0..95 + - OPERATION_DEFINITION@0..93 + - DESCRIPTION@0..67 + - STRING_VALUE@0..67 + - STRING@0..67 "\"Operation with description - now supported in September 2025 spec\"" + - WHITESPACE@67..68 "\n" + - OPERATION_TYPE@68..73 + - query_KW@68..73 "query" + - WHITESPACE@73..74 " " + - NAME@74..83 + - IDENT@74..83 "TestQuery" + - WHITESPACE@83..84 " " + - SELECTION_SET@84..93 + - L_CURLY@84..85 "{" + - WHITESPACE@85..86 " " + - FIELD@86..91 + - NAME@86..91 + - IDENT@86..91 "field" + - WHITESPACE@91..92 " " + - R_CURLY@92..93 "}" + - WHITESPACE@93..95 "\n\n" +recursion limit: 500, high: 1 \ No newline at end of file diff --git a/crates/apollo-smith/src/fragment.rs b/crates/apollo-smith/src/fragment.rs index 310084b59..1ddc24fa0 100644 --- a/crates/apollo-smith/src/fragment.rs +++ b/crates/apollo-smith/src/fragment.rs @@ -25,6 +25,7 @@ pub struct FragmentDef { impl From for ast::Definition { fn from(x: FragmentDef) -> Self { ast::FragmentDefinition { + description: None, name: x.name.into(), type_condition: x.type_condition.name.into(), directives: Directive::to_ast(x.directives), diff --git a/crates/apollo-smith/src/operation.rs b/crates/apollo-smith/src/operation.rs index fc2b8ea2b..675e526ec 100644 --- a/crates/apollo-smith/src/operation.rs +++ b/crates/apollo-smith/src/operation.rs @@ -28,6 +28,7 @@ pub struct OperationDef { impl From for ast::Definition { fn from(x: OperationDef) -> Self { ast::OperationDefinition { + description: None, operation_type: x.operation_type.into(), name: x.name.map(Into::into), directives: Directive::to_ast(x.directives), diff --git a/crates/apollo-smith/src/variable.rs b/crates/apollo-smith/src/variable.rs index e40f0e036..47001a16b 100644 --- a/crates/apollo-smith/src/variable.rs +++ b/crates/apollo-smith/src/variable.rs @@ -27,6 +27,7 @@ pub struct VariableDef { impl From for ast::VariableDefinition { fn from(x: VariableDef) -> Self { Self { + description: None, name: x.name.into(), ty: Node::new(x.ty.into()), default_value: x.default_value.map(|x| Node::new(x.into())), diff --git a/graphql.ungram b/graphql.ungram index b2efb326e..2669b9ba0 100644 --- a/graphql.ungram +++ b/graphql.ungram @@ -39,7 +39,7 @@ Definition = | InputObjectTypeExtension OperationDefinition = - OperationType Name? VariableDefinitions? Directives? SelectionSet + Description? OperationType Name? VariableDefinitions? Directives? SelectionSet | SelectionSet OperationType = @@ -74,7 +74,7 @@ InlineFragment = '...' TypeCondition? Directives? SelectionSet FragmentDefinition = - 'fragment' FragmentName TypeCondition Directives? SelectionSet + Description? 'fragment' FragmentName TypeCondition Directives? SelectionSet FragmentName = Name @@ -127,7 +127,7 @@ VariableDefinitions = '(' VariableDefinition* ')' VariableDefinition = - Variable ':' Type DefaultValue? Directives? + Description? Variable ':' Type DefaultValue? Directives? Variable = '$' Name