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..1b02b01ef 100644 --- a/crates/apollo-compiler/src/ast/serialize.rs +++ b/crates/apollo-compiler/src/ast/serialize.rs @@ -194,6 +194,7 @@ 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, @@ -208,6 +209,7 @@ impl OperationDefinition { && variables.is_empty() && directives.is_empty(); if !shorthand { + serialize_description(state, description)?; state.write(operation_type.name())?; if let Some(name) = &name { state.write(" ")?; @@ -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/diagnostics/0125_query_shorthand_description.graphql b/crates/apollo-compiler/test_data/diagnostics/0125_query_shorthand_description.graphql new file mode 100644 index 000000000..6feea155c --- /dev/null +++ b/crates/apollo-compiler/test_data/diagnostics/0125_query_shorthand_description.graphql @@ -0,0 +1,14 @@ +"Get all our time machine models." +{ + timeMachines { + model + } +} + +type TimeMachine { + id: ID! + model: String +} +type Query { + timeMachines: [TimeMachine] +} 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_executable_descriptions.graphql b/crates/apollo-compiler/test_data/ok/0118_executable_descriptions.graphql new file mode 100644 index 000000000..0d1fe99a9 --- /dev/null +++ b/crates/apollo-compiler/test_data/ok/0118_executable_descriptions.graphql @@ -0,0 +1,44 @@ +""" +Request the current status of a time machine and its operator. +You can also check the status for a particular year. +**Warning:** certain years may trigger an anomaly in the space-time continuum. +""" +query GetTimeMachineStatus( + "The unique serial number of the time machine to inspect." + $machineId: ID! + "The year to check the status for." + $year: Int +) { + timeMachine(id: $machineId) { + ...TimeMachineDetails + status(year: $year) + } +} + +"Details about a time machine and its operator." +fragment TimeMachineDetails on TimeMachine { + id + model + lastMaintenance + operator { + name + licenseLevel + } +} + +scalar Date + +type TimeMachine { + id: ID! + status(year: Int): String + model: String + lastMaintenance: Date + operator: Operator +} +type Operator { + name: String! + licenseLevel: Int +} +type Query { + timeMachine(id: ID!): TimeMachine +} diff --git a/crates/apollo-compiler/test_data/ok/0118_executable_descriptions.txt b/crates/apollo-compiler/test_data/ok/0118_executable_descriptions.txt new file mode 100644 index 000000000..db4bc9e2d --- /dev/null +++ b/crates/apollo-compiler/test_data/ok/0118_executable_descriptions.txt @@ -0,0 +1,477 @@ +Schema { + sources: { + 1: SourceFile { + path: "built_in.graphql", + source_text: include_str!("built_in.graphql"), + }, + 47: SourceFile { + path: "0118_executable_descriptions.graphql", + source_text: "\"\"\"\nRequest the current status of a time machine and its operator.\nYou can also check the status for a particular year.\n**Warning:** certain years may trigger an anomaly in the space-time continuum.\n\"\"\"\nquery GetTimeMachineStatus(\n \"The unique serial number of the time machine to inspect.\"\n $machineId: ID!\n \"The year to check the status for.\"\n $year: Int\n) {\n timeMachine(id: $machineId) {\n ...TimeMachineDetails\n status(year: $year)\n }\n}\n\n\"Details about a time machine and its operator.\"\nfragment TimeMachineDetails on TimeMachine {\n id\n model\n lastMaintenance\n operator {\n name\n licenseLevel\n }\n}\n\nscalar Date\n\ntype TimeMachine {\n id: ID!\n status(year: Int): String\n model: String\n lastMaintenance: Date\n operator: Operator\n}\ntype Operator {\n name: String!\n licenseLevel: Int\n}\ntype Query {\n timeMachine(id: ID!): TimeMachine\n}\n", + }, + }, + schema_definition: SchemaDefinition { + description: None, + directives: [], + query: Some( + ComponentName { + origin: Definition, + name: "Query", + }, + ), + mutation: None, + subscription: None, + }, + directive_definitions: { + "skip": built_in_directive!("skip"), + "include": built_in_directive!("include"), + "deprecated": built_in_directive!("deprecated"), + "specifiedBy": built_in_directive!("specifiedBy"), + }, + types: { + "__Schema": built_in_type!("__Schema"), + "__Type": built_in_type!("__Type"), + "__TypeKind": built_in_type!("__TypeKind"), + "__Field": built_in_type!("__Field"), + "__InputValue": built_in_type!("__InputValue"), + "__EnumValue": built_in_type!("__EnumValue"), + "__Directive": built_in_type!("__Directive"), + "__DirectiveLocation": built_in_type!("__DirectiveLocation"), + "Int": built_in_type!("Int"), + "String": built_in_type!("String"), + "Boolean": built_in_type!("Boolean"), + "ID": built_in_type!("ID"), + "Date": Scalar( + 625..636 @47 ScalarType { + description: None, + name: "Date", + directives: [], + }, + ), + "TimeMachine": Object( + 638..757 @47 ObjectType { + description: None, + name: "TimeMachine", + implements_interfaces: {}, + directives: [], + fields: { + "id": Component { + origin: Definition, + node: 659..666 @47 FieldDefinition { + description: None, + name: "id", + arguments: [], + ty: NonNullNamed( + "ID", + ), + directives: [], + }, + }, + "status": Component { + origin: Definition, + node: 669..694 @47 FieldDefinition { + description: None, + name: "status", + arguments: [ + 676..685 @47 InputValueDefinition { + description: None, + name: "year", + ty: 682..685 @47 Named( + "Int", + ), + default_value: None, + directives: [], + }, + ], + ty: Named( + "String", + ), + directives: [], + }, + }, + "model": Component { + origin: Definition, + node: 697..710 @47 FieldDefinition { + description: None, + name: "model", + arguments: [], + ty: Named( + "String", + ), + directives: [], + }, + }, + "lastMaintenance": Component { + origin: Definition, + node: 713..734 @47 FieldDefinition { + description: None, + name: "lastMaintenance", + arguments: [], + ty: Named( + "Date", + ), + directives: [], + }, + }, + "operator": Component { + origin: Definition, + node: 737..755 @47 FieldDefinition { + description: None, + name: "operator", + arguments: [], + ty: Named( + "Operator", + ), + directives: [], + }, + }, + }, + }, + ), + "Operator": Object( + 758..811 @47 ObjectType { + description: None, + name: "Operator", + implements_interfaces: {}, + directives: [], + fields: { + "name": Component { + origin: Definition, + node: 776..789 @47 FieldDefinition { + description: None, + name: "name", + arguments: [], + ty: NonNullNamed( + "String", + ), + directives: [], + }, + }, + "licenseLevel": Component { + origin: Definition, + node: 792..809 @47 FieldDefinition { + description: None, + name: "licenseLevel", + arguments: [], + ty: Named( + "Int", + ), + directives: [], + }, + }, + }, + }, + ), + "Query": Object( + 812..862 @47 ObjectType { + description: None, + name: "Query", + implements_interfaces: {}, + directives: [], + fields: { + "timeMachine": Component { + origin: Definition, + node: 827..860 @47 FieldDefinition { + description: None, + name: "timeMachine", + arguments: [ + 839..846 @47 InputValueDefinition { + description: None, + name: "id", + ty: 843..846 @47 NonNullNamed( + "ID", + ), + default_value: None, + directives: [], + }, + ], + ty: Named( + "TimeMachine", + ), + directives: [], + }, + }, + }, + }, + ), + }, +} +ExecutableDocument { + sources: { + 1: SourceFile { + path: "built_in.graphql", + source_text: include_str!("built_in.graphql"), + }, + 47: SourceFile { + path: "0118_executable_descriptions.graphql", + source_text: "\"\"\"\nRequest the current status of a time machine and its operator.\nYou can also check the status for a particular year.\n**Warning:** certain years may trigger an anomaly in the space-time continuum.\n\"\"\"\nquery GetTimeMachineStatus(\n \"The unique serial number of the time machine to inspect.\"\n $machineId: ID!\n \"The year to check the status for.\"\n $year: Int\n) {\n timeMachine(id: $machineId) {\n ...TimeMachineDetails\n status(year: $year)\n }\n}\n\n\"Details about a time machine and its operator.\"\nfragment TimeMachineDetails on TimeMachine {\n id\n model\n lastMaintenance\n operator {\n name\n licenseLevel\n }\n}\n\nscalar Date\n\ntype TimeMachine {\n id: ID!\n status(year: Int): String\n model: String\n lastMaintenance: Date\n operator: Operator\n}\ntype Operator {\n name: String!\n licenseLevel: Int\n}\ntype Query {\n timeMachine(id: ID!): TimeMachine\n}\n", + }, + }, + operations: OperationMap { + anonymous: None, + named: { + "GetTimeMachineStatus": 0..452 @47 Operation { + description: Some( + 0..202 @47 "Request the current status of a time machine and its operator.\nYou can also check the status for a particular year.\n**Warning:** certain years may trigger an anomaly in the space-time continuum.", + ), + operation_type: Query, + name: Some( + "GetTimeMachineStatus", + ), + variables: [ + 233..309 @47 VariableDefinition { + description: Some( + 233..291 @47 "The unique serial number of the time machine to inspect.", + ), + name: "machineId", + ty: 306..309 @47 NonNullNamed( + "ID", + ), + default_value: None, + directives: [], + }, + 312..360 @47 VariableDefinition { + description: Some( + 312..347 @47 "The year to check the status for.", + ), + name: "year", + ty: 357..360 @47 Named( + "Int", + ), + default_value: None, + directives: [], + }, + ], + directives: [], + selection_set: SelectionSet { + ty: "Query", + selections: [ + Field( + 367..450 @47 Field { + definition: 827..860 @47 FieldDefinition { + description: None, + name: "timeMachine", + arguments: [ + 839..846 @47 InputValueDefinition { + description: None, + name: "id", + ty: 843..846 @47 NonNullNamed( + "ID", + ), + default_value: None, + directives: [], + }, + ], + ty: Named( + "TimeMachine", + ), + directives: [], + }, + alias: None, + name: "timeMachine", + arguments: [ + 379..393 @47 Argument { + name: "id", + value: 383..393 @47 Variable( + "machineId", + ), + }, + ], + directives: [], + selection_set: SelectionSet { + ty: "TimeMachine", + selections: [ + FragmentSpread( + 401..422 @47 FragmentSpread { + fragment_name: "TimeMachineDetails", + directives: [], + }, + ), + Field( + 427..446 @47 Field { + definition: 669..694 @47 FieldDefinition { + description: None, + name: "status", + arguments: [ + 676..685 @47 InputValueDefinition { + description: None, + name: "year", + ty: 682..685 @47 Named( + "Int", + ), + default_value: None, + directives: [], + }, + ], + ty: Named( + "String", + ), + directives: [], + }, + alias: None, + name: "status", + arguments: [ + 434..445 @47 Argument { + name: "year", + value: 440..445 @47 Variable( + "year", + ), + }, + ], + directives: [], + selection_set: SelectionSet { + ty: "String", + selections: [], + }, + }, + ), + ], + }, + }, + ), + ], + }, + }, + }, + }, + fragments: { + "TimeMachineDetails": 454..623 @47 Fragment { + description: Some( + 454..502 @47 "Details about a time machine and its operator.", + ), + name: "TimeMachineDetails", + directives: [], + selection_set: SelectionSet { + ty: "TimeMachine", + selections: [ + Field( + 550..552 @47 Field { + definition: 659..666 @47 FieldDefinition { + description: None, + name: "id", + arguments: [], + ty: NonNullNamed( + "ID", + ), + directives: [], + }, + alias: None, + name: "id", + arguments: [], + directives: [], + selection_set: SelectionSet { + ty: "ID", + selections: [], + }, + }, + ), + Field( + 555..560 @47 Field { + definition: 697..710 @47 FieldDefinition { + description: None, + name: "model", + arguments: [], + ty: Named( + "String", + ), + directives: [], + }, + alias: None, + name: "model", + arguments: [], + directives: [], + selection_set: SelectionSet { + ty: "String", + selections: [], + }, + }, + ), + Field( + 563..578 @47 Field { + definition: 713..734 @47 FieldDefinition { + description: None, + name: "lastMaintenance", + arguments: [], + ty: Named( + "Date", + ), + directives: [], + }, + alias: None, + name: "lastMaintenance", + arguments: [], + directives: [], + selection_set: SelectionSet { + ty: "Date", + selections: [], + }, + }, + ), + Field( + 581..621 @47 Field { + definition: 737..755 @47 FieldDefinition { + description: None, + name: "operator", + arguments: [], + ty: Named( + "Operator", + ), + directives: [], + }, + alias: None, + name: "operator", + arguments: [], + directives: [], + selection_set: SelectionSet { + ty: "Operator", + selections: [ + Field( + 596..600 @47 Field { + definition: 776..789 @47 FieldDefinition { + description: None, + name: "name", + arguments: [], + ty: NonNullNamed( + "String", + ), + directives: [], + }, + alias: None, + name: "name", + arguments: [], + directives: [], + selection_set: SelectionSet { + ty: "String", + selections: [], + }, + }, + ), + Field( + 605..617 @47 Field { + definition: 792..809 @47 FieldDefinition { + description: None, + name: "licenseLevel", + arguments: [], + ty: Named( + "Int", + ), + directives: [], + }, + alias: None, + name: "licenseLevel", + arguments: [], + directives: [], + selection_set: SelectionSet { + ty: "Int", + selections: [], + }, + }, + ), + ], + }, + }, + ), + ], + }, + }, + }, +} diff --git a/crates/apollo-compiler/test_data/serializer/diagnostics/0125_query_shorthand_description.graphql b/crates/apollo-compiler/test_data/serializer/diagnostics/0125_query_shorthand_description.graphql new file mode 100644 index 000000000..db9e0a177 --- /dev/null +++ b/crates/apollo-compiler/test_data/serializer/diagnostics/0125_query_shorthand_description.graphql @@ -0,0 +1,14 @@ +{ + timeMachines { + model + } +} + +type TimeMachine { + id: ID! + model: String +} + +type Query { + timeMachines: [TimeMachine] +} diff --git a/crates/apollo-compiler/test_data/serializer/ok/0118_executable_descriptions.graphql b/crates/apollo-compiler/test_data/serializer/ok/0118_executable_descriptions.graphql new file mode 100644 index 000000000..12f55de44 --- /dev/null +++ b/crates/apollo-compiler/test_data/serializer/ok/0118_executable_descriptions.graphql @@ -0,0 +1,41 @@ +""" +Request the current status of a time machine and its operator. +You can also check the status for a particular year. +**Warning:** certain years may trigger an anomaly in the space-time continuum. +""" +query GetTimeMachineStatus("The unique serial number of the time machine to inspect." $machineId: ID!, "The year to check the status for." $year: Int) { + timeMachine(id: $machineId) { + ...TimeMachineDetails + status(year: $year) + } +} + +"""Details about a time machine and its operator.""" +fragment TimeMachineDetails on TimeMachine { + id + model + lastMaintenance + operator { + name + licenseLevel + } +} + +scalar Date + +type TimeMachine { + id: ID! + status(year: Int): String + model: String + lastMaintenance: Date + operator: Operator +} + +type Operator { + name: String! + licenseLevel: Int +} + +type Query { + timeMachine(id: ID!): TimeMachine +} 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..94f339513 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; @@ -15,6 +16,11 @@ use crate::T; /// **fragment** FragmentName TypeCondition Directives? SelectionSet pub(crate) fn fragment_definition(p: &mut Parser) { let _g = p.start_node(SyntaxKind::FRAGMENT_DEFINITION); + + if let Some(TokenKind::StringValue) = p.peek() { + description::description(p); + } + p.bump(SyntaxKind::fragment_KW); fragment_name(p); diff --git a/crates/apollo-parser/src/parser/grammar/operation.rs b/crates/apollo-parser/src/parser/grammar/operation.rs index 0b6cf98c9..51bec19c0 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; @@ -14,10 +15,17 @@ use crate::T; /// OperationType Name? VariableDefinitions? Directives? SelectionSet /// SelectionSet pub(crate) fn operation_definition(p: &mut Parser) { + let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION); + + let description_token = p.peek_token() + .filter(|token| token.kind() == TokenKind::StringValue) + .cloned(); + if description_token.is_some() { + description::description(p); + } + match p.peek() { Some(TokenKind::Name) => { - let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION); - operation_type(p); if let Some(TokenKind::Name) = p.peek() { @@ -38,8 +46,9 @@ pub(crate) fn operation_definition(p: &mut Parser) { } } Some(T!['{']) => { - let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION); - + if let Some(description_token) = description_token { + p.err_at_token(&description_token, "shorthand operation must not have a description"); + } selection::selection_set(p) } _ => p.err_and_pop("expected an Operation Type or a Selection Set"), diff --git a/crates/apollo-parser/src/parser/grammar/variable.rs b/crates/apollo-parser/src/parser/grammar/variable.rs index 55209605c..e1ba80f61 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; @@ -8,6 +9,7 @@ use crate::SyntaxKind; use crate::TokenKind; use crate::S; use crate::T; +use std::ops::ControlFlow; /// See: https://spec.graphql.org/October2021/#VariableDefinitions /// @@ -17,12 +19,18 @@ 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() { + if let Some(T![$] | TokenKind::StringValue) = p.peek() { variable_definition(p); } else { p.err("expected a Variable Definition") } - p.peek_while_kind(T![$], variable_definition); + p.peek_while(|p, kind| match kind { + T![$] | TokenKind::StringValue => { + variable_definition(p); + ControlFlow::Continue(()) + } + _ => ControlFlow::Break(()), + }); p.expect(T![')'], S![')']); } @@ -33,6 +41,11 @@ pub(crate) fn variable_definitions(p: &mut Parser) { /// Variable **:** Type DefaultValue? Directives[Const]? pub(crate) fn variable_definition(p: &mut Parser) { let _guard = p.start_node(SyntaxKind::VARIABLE_DEFINITION); + + if let Some(TokenKind::StringValue) = p.peek() { + description::description(p); + } + variable(p); if let Some(T![:]) = p.peek() { diff --git a/crates/apollo-smith/src/fragment.rs b/crates/apollo-smith/src/fragment.rs index 310084b59..e1172bef7 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, // TODO(@goto-bus-stop): represent description 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..a8a9a2edb 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, // TODO(@goto-bus-stop): represent description 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..339ed655c 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, // TODO(@goto-bus-stop): represent description 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..1b365fae8 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 @@ -286,4 +286,4 @@ DirectiveLocation = | 'ENUM' | 'ENUM_VALUE' | 'INPUT_OBJECT' - | 'INPUT_FIELD_DEFINITION' \ No newline at end of file + | 'INPUT_FIELD_DEFINITION'