Mojom parser: Compute and validate struct field ordinals. In mojom_types.mojom struct fields are supposed to be listed in ordinal order, and the original lexical order is preserved in a field of DeclarationData called |declaration_order|. Additionally there is a field of DeclarationData called |declared_ordinal| that records if an explicit ordinal has been specified. Previously only the |declared_ordinal| bit was implemented. This has worked so far because the actual field ordinals are currently computed in the Python back-end using the |declared_ordinal| field. This CL implements the missing bits which will allow us in a follow-up CL to eliminate the logic from the Python backend. Implementing the missing bits is also important because we are starting to re-write the backends in Go and also because the runtime type information requires it. This CL only deals with struct fields. There will be follow-up CLs for union fields and other things. Note that some ordinals are already being fully handled by the parser, namely method ordinals. BUG=696 R=azani@chromium.org Review URL: https://codereview.chromium.org/1767033002 .
diff --git a/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1 b/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1 index 63f1960..346ce12 100644 --- a/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1 +++ b/mojo/public/tools/bindings/mojom_tool/bin/linux64/mojom.sha1
@@ -1 +1 @@ -52754acd9f19c091113ffd6a7cc15bdbd894ffec \ No newline at end of file +79987c1fd81b4941aee5c6ee08ee04d268ba64a3 \ No newline at end of file
diff --git a/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1 b/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1 index e829ce9..7939d8e 100644 --- a/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1 +++ b/mojo/public/tools/bindings/mojom_tool/bin/mac64/mojom.sha1
@@ -1 +1 @@ -5d974a5aae75a7a76ea34a4826c1372e409cb38e \ No newline at end of file +bb5eb7d890b76a48e2699ff5d03f153f4c3ec66f \ No newline at end of file
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator.py b/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator.py index 2ae6060..23f59b1 100755 --- a/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator.py
@@ -190,7 +190,11 @@ assert mojom_type.tag == mojom_types_mojom.UserDefinedType.Tags.struct_type mojom_struct = mojom_type.struct_type self.PopulateUserDefinedType(struct, mojom_struct) - struct.fields = [self.StructFieldFromMojom(f) for f in mojom_struct.fields] + # mojom_struct.fields is indexed by the field ordinals. We want + # to capture these ordinals but sort struct.fields by declaration_order. + struct.fields = [self.StructFieldFromMojom(ordinal, f) for (ordinal, f) in + enumerate(mojom_struct.fields)] + struct.fields.sort(key=lambda field: field.declaration_order) self.PopulateContainedDeclarationsFromMojom( struct, mojom_struct.decl_data.contained_declarations) @@ -208,10 +212,13 @@ union_field.ordinal = self.OrdinalFromMojom(mojom_field) return union_field - def StructFieldFromMojom(self, mojom_field): + def StructFieldFromMojom(self, ordinal, mojom_field): """Translates a mojom_types_mojom.StructField to a module.StructField. Args: + ordinal: {int} The 0-based ordinal position of the field within the + struct. Note that this is not necessarily the same as the lexical + order or the packing order. mojom_field: {mojom_types_mojom.StructField} to be translated. Returns: @@ -219,7 +226,13 @@ """ struct_field = module.StructField() self.PopulateCommonFieldValues(struct_field, mojom_field) + # Note that the |ordinal| attribute of |struct_field| records only the + # *declared* ordinal and as such is not defined for every field whereas + # the |computed_ordinal| attribute is defined for every field. If + # |ordinal| is defined then it is equal to |computed_ordinal|. struct_field.ordinal = self.OrdinalFromMojom(mojom_field) + struct_field.computed_ordinal = ordinal + struct_field.declaration_order = mojom_field.decl_data.declaration_order if mojom_field.default_value: if (mojom_field.default_value.tag == mojom_types_mojom.DefaultFieldValue.Tags.default_keyword):
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator_unittest.py b/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator_unittest.py index 6b177e3..ab96d64 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator_unittest.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/mojom_translator_unittest.py
@@ -243,21 +243,32 @@ mojom_struct = mojom_types_mojom.MojomStruct( decl_data=mojom_types_mojom.DeclarationData(short_name='FirstStruct')) mojom_struct.fields = [ - mojom_types_mojom.StructField( + mojom_types_mojom.StructField( decl_data=mojom_types_mojom.DeclarationData( - short_name='field01', - declared_ordinal=5), + short_name='field03', + declaration_order=2), type=mojom_types_mojom.Type( simple_type=mojom_types_mojom.SimpleType.BOOL)), mojom_types_mojom.StructField( decl_data=mojom_types_mojom.DeclarationData( - short_name='field02'), + short_name='field01', + declared_ordinal=1, + declaration_order=0), + type=mojom_types_mojom.Type( + simple_type=mojom_types_mojom.SimpleType.BOOL)), + mojom_types_mojom.StructField( + decl_data=mojom_types_mojom.DeclarationData( + short_name='field02', + declaration_order=1), type=mojom_types_mojom.Type( simple_type=mojom_types_mojom.SimpleType.DOUBLE), default_value=mojom_types_mojom.DefaultFieldValue( value=mojom_types_mojom.Value( literal_value=mojom_types_mojom.LiteralValue(double_value=15)))), ] + # mojom_fields_declaration_order lists, in declaration order, the indices + # of the fields in mojom_types_mojom.StructField. + mojom_fields_declaration_order = [1, 2, 0] mojom_struct.decl_data.source_file_info = mojom_types_mojom.SourceFileInfo( file_name=mojom_file.file_name) @@ -270,14 +281,19 @@ self.assertEquals(translator._module, struct.module) self.assertEquals(len(mojom_struct.fields), len(struct.fields)) - for gold, f in zip(mojom_struct.fields, struct.fields): + for index, gold_index in enumerate(mojom_fields_declaration_order): + gold = mojom_struct.fields[gold_index] + f = struct.fields[index] self.assertEquals(f.name, gold.decl_data.short_name) + if gold.decl_data.declared_ordinal >= 0: + self.assertEquals(gold.decl_data.declared_ordinal, f.ordinal) + else: + self.assertEquals(None, f.ordinal) + self.assertEquals(gold_index, f.computed_ordinal) self.assertEquals(module.BOOL, struct.fields[0].kind) - self.assertEquals(5, struct.fields[0].ordinal) - self.assertEquals(module.DOUBLE, struct.fields[1].kind) - self.assertEquals(None, struct.fields[1].ordinal) + self.assertEquals('15.0', struct.fields[1].default) def test_constant(self):
diff --git a/mojom/mojom_parser/mojom/user_defined_types.go b/mojom/mojom_parser/mojom/user_defined_types.go index 6fb8064..4f1f798 100644 --- a/mojom/mojom_parser/mojom/user_defined_types.go +++ b/mojom/mojom_parser/mojom/user_defined_types.go
@@ -331,8 +331,9 @@ structType StructType - fieldsByName map[string]*StructField - Fields []*StructField + fieldsByName map[string]*StructField + FieldsInLexicalOrder []*StructField + fieldsInOrdinalOrder []*StructField // Used to form an error message in case of a duplicate field name. userFacingName string @@ -341,7 +342,7 @@ func NewMojomStruct(declData DeclarationData) *MojomStruct { mojomStruct := new(MojomStruct) mojomStruct.fieldsByName = make(map[string]*StructField) - mojomStruct.Fields = make([]*StructField, 0) + mojomStruct.FieldsInLexicalOrder = make([]*StructField, 0) mojomStruct.Init(declData, mojomStruct) mojomStruct.userFacingName = mojomStruct.simpleName return mojomStruct @@ -409,11 +410,19 @@ } } s.fieldsByName[field.simpleName] = field - s.Fields = append(s.Fields, field) + field.lexicalPosition = int32(len(s.FieldsInLexicalOrder)) + s.FieldsInLexicalOrder = append(s.FieldsInLexicalOrder, field) s.DeclaredObjects = append(s.DeclaredObjects, field) return nil } +func (s *MojomStruct) FieldsInOrdinalOrder() []*StructField { + if s.fieldsInOrdinalOrder == nil { + panic("The method ComputeFieldOrdinals() must be invoked first.") + } + return s.fieldsInOrdinalOrder +} + func (*MojomStruct) Kind() UserDefinedTypeKind { return UserDefinedTypeKindStruct } @@ -426,10 +435,67 @@ return value.IsDefault() } +var ErrOrdinalRange = errors.New("ordinal value out of range") +var ErrOrdinalDuplicate = errors.New("duplicate ordinal value") + +type StructFieldOrdinalError struct { + Ord int64 // The attemted ordinal + StructName string // The name of the struct in which the problem occurs. + Field *StructField // The field with the attempted ordinal + ExistingField *StructField // Used if Err == ErrOrdinalDuplicate + Err error // the type of error (ErrOrdinalRange, ErrOrdinalDuplicate) +} + +// StructFieldOrdinalError implements error. +func (e *StructFieldOrdinalError) Error() string { + var message string + switch e.Err { + case ErrOrdinalRange: + message = fmt.Sprintf("Invalid ordinal for field %s: %d. "+ + "A struct field ordinal must be a non-negative integer value "+ + "less than the number of fields in the struct.", + e.Field.SimpleName(), e.Ord) + case ErrOrdinalDuplicate: + message = fmt.Sprintf("Invalid ordinal for field %s: %d. "+ + "There is already a field in struct %s with that ordinal: %s.", + e.Field.SimpleName(), e.Ord, e.StructName, + e.ExistingField.SimpleName()) + default: + panic(fmt.Sprintf("Unrecognized type of MethodOrdinalError %v", e.Err)) + } + return UserErrorMessage(e.Field.OwningFile(), e.Field.NameToken(), message) +} + // This should be invoked some time after all of the fields have been added // to the struct. -func (s *MojomStruct) ComputeFieldOrdinals() { - // TODO(rudominer) Implement MojomStruct.ComputeFieldOrdinals() +func (s *MojomStruct) ComputeFieldOrdinals() error { + numFields := uint32(len(s.FieldsInLexicalOrder)) + s.fieldsInOrdinalOrder = make([]*StructField, numFields) + nextOrdinal := uint32(0) + for _, field := range s.FieldsInLexicalOrder { + fieldOrdinal := nextOrdinal + if field.declaredOrdinal >= 0 { + if field.declaredOrdinal >= math.MaxUint32 { + return &StructFieldOrdinalError{Ord: field.declaredOrdinal, + StructName: s.SimpleName(), Field: field, + Err: ErrOrdinalRange} + } + fieldOrdinal = uint32(field.declaredOrdinal) + } + if fieldOrdinal >= numFields { + return &StructFieldOrdinalError{Ord: int64(fieldOrdinal), + StructName: s.SimpleName(), Field: field, + Err: ErrOrdinalRange} + } + if existingField := s.fieldsInOrdinalOrder[fieldOrdinal]; existingField != nil { + return &StructFieldOrdinalError{Ord: int64(fieldOrdinal), + StructName: s.SimpleName(), Field: field, + ExistingField: existingField, Err: ErrOrdinalDuplicate} + } + s.fieldsInOrdinalOrder[fieldOrdinal] = field + nextOrdinal = fieldOrdinal + 1 + } + return nil } func (m MojomStruct) String() string { @@ -437,7 +503,7 @@ s += fmt.Sprintf("%s\n", m.UserDefinedTypeBase) s += " Fields\n" s += " ------\n" - for _, field := range m.Fields { + for _, field := range m.FieldsInLexicalOrder { s += fmt.Sprintf(" %s\n", field) } s += " Enums\n" @@ -457,7 +523,7 @@ // is being used to represent the parameters to a method. func (s MojomStruct) ParameterString() string { str := "" - for i, f := range s.Fields { + for i, f := range s.FieldsInLexicalOrder { if i > 0 { str += ", " } @@ -613,9 +679,6 @@ return false } -var ErrOrdinalRange = errors.New("ordinal value out of range") -var ErrOrdinalDuplicate = errors.New("duplicate ordinal value") - type MethodOrdinalError struct { Ord int64 // The attemted ordinal InterfaceName string // The name of the interface in which the problem occurs. @@ -1210,6 +1273,11 @@ // We use int64 here because valid ordinals are uint32 and we want to // be able to represent an unset value as -1. declaredOrdinal int64 + + // The zero-based position of this element within its containing + // lexical scope as it appears in the Mojom declaration, or -1 + // if this is not set. + lexicalPosition int32 } func DeclData(name string, owningFile *MojomFile, nameToken lexer.Token, attributes *Attributes) DeclarationData { @@ -1219,7 +1287,7 @@ func DeclDataWithOrdinal(name string, owningFile *MojomFile, nameToken lexer.Token, attributes *Attributes, declaredOrdinal int64) DeclarationData { return DeclarationData{simpleName: name, owningFile: owningFile, nameToken: nameToken, - attributes: attributes, declaredOrdinal: declaredOrdinal} + attributes: attributes, declaredOrdinal: declaredOrdinal, lexicalPosition: -1} } func (d *DeclarationData) SimpleName() string { @@ -1254,6 +1322,10 @@ return d.declaredOrdinal } +func (d *DeclarationData) LexicalPosition() int32 { + return d.lexicalPosition +} + func (d *DeclarationData) OwningFile() *MojomFile { return d.owningFile }
diff --git a/mojom/mojom_parser/parser/comment_merger_test.go b/mojom/mojom_parser/parser/comment_merger_test.go index fdce0c0..45c75b3 100644 --- a/mojom/mojom_parser/parser/comment_merger_test.go +++ b/mojom/mojom_parser/parser/comment_merger_test.go
@@ -66,7 +66,7 @@ // Sanity-check that we got the right method. checkEq("Method1", method1.SimpleName()) - inParam1 := method1.Parameters.Fields[0] + inParam1 := method1.Parameters.FieldsInLexicalOrder[0] // Sanity-check that we got the right field. checkEq("in_param1", inParam1.SimpleName())
diff --git a/mojom/mojom_parser/parser/parser_test.go b/mojom/mojom_parser/parser/parser_test.go index 54cc3da..c0fc317 100644 --- a/mojom/mojom_parser/parser/parser_test.go +++ b/mojom/mojom_parser/parser/parser_test.go
@@ -198,7 +198,7 @@ import "and.another.file"; struct Foo{ - [happy=true] int32 x@4; + [happy=true] int32 x@0; };` { expectedFile.AddImport(mojom.NewImportedFile("another.file", nil)) @@ -208,7 +208,7 @@ structFoo.InitAsScope(mojom.NewTestFileScope("test.scope")) attributes := mojom.NewAttributes(lexer.Token{}) attributes.List = append(attributes.List, mojom.NewMojomAttribute("happy", nil, mojom.MakeBoolLiteralValue(true, nil))) - structFoo.AddField(mojom.NewStructField(mojom.DeclTestDataAWithOrdinal("x", attributes, 4), mojom.SimpleTypeInt32, nil)) + structFoo.AddField(mojom.NewStructField(mojom.DeclTestDataAWithOrdinal("x", attributes, 0), mojom.SimpleTypeInt32, nil)) expectedFile.AddStruct(structFoo) } endTestCase() @@ -224,10 +224,10 @@ import "and.another.file"; struct Foo{ - int32 x@4 = 42; + int32 x@0 = 42; [age=7, level="high"] string y = "Howdy!"; string? z; - bool w@6 = false; + bool w@3 = false; };` { expectedFile.AddImport(mojom.NewImportedFile("another.file", nil)) @@ -235,13 +235,13 @@ structFoo := mojom.NewMojomStruct(mojom.DeclTestData("Foo")) structFoo.InitAsScope(mojom.NewTestFileScope("test.scope")) - structFoo.AddField(mojom.NewStructField(mojom.DeclTestDataWithOrdinal("x", 4), mojom.SimpleTypeInt32, mojom.MakeInt8LiteralValue(42, nil))) + structFoo.AddField(mojom.NewStructField(mojom.DeclTestDataWithOrdinal("x", 0), mojom.SimpleTypeInt32, mojom.MakeInt8LiteralValue(42, nil))) attributes := mojom.NewAttributes(lexer.Token{}) attributes.List = append(attributes.List, mojom.NewMojomAttribute("age", nil, mojom.MakeInt8LiteralValue(7, nil))) attributes.List = append(attributes.List, mojom.NewMojomAttribute("level", nil, mojom.MakeStringLiteralValue("high", nil))) structFoo.AddField(mojom.NewStructField(mojom.DeclTestDataA("y", attributes), mojom.BuiltInType("string"), mojom.MakeStringLiteralValue("Howdy!", nil))) structFoo.AddField(mojom.NewStructField(mojom.DeclTestData("z"), mojom.BuiltInType("string?"), nil)) - structFoo.AddField(mojom.NewStructField(mojom.DeclTestDataWithOrdinal("w", 6), mojom.BuiltInType("bool"), mojom.MakeBoolLiteralValue(false, nil))) + structFoo.AddField(mojom.NewStructField(mojom.DeclTestDataWithOrdinal("w", 3), mojom.BuiltInType("bool"), mojom.MakeBoolLiteralValue(false, nil))) expectedFile.AddStruct(structFoo) } endTestCase() @@ -515,6 +515,141 @@ endTestCase() //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: empty string + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x@; + }; + + ` + expectError("field \"x\": Invalid ordinal string following '@'") + expectError("Ordinals must be decimal integers between 0 and 4294967294") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: Not a number + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x@happy; + }; + + ` + expectError("field \"x\": Invalid ordinal string following '@'") + expectError("Ordinals must be decimal integers between 0 and 4294967294") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: Negative + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x@-500; + }; + + ` + expectError("field \"x\": Invalid ordinal string following '@'") + expectError("Ordinals must be decimal integers between 0 and 4294967294") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: too big for uint32) + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x@4294967295; + }; + + ` + expectError("field \"x\": Invalid ordinal string following '@'") + expectError("4294967295") + expectError("Ordinals must be decimal integers between 0 and 4294967294") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: too big for uint64) + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x@999999999999999999999999999999999999999; + }; + + ` + expectError("field \"x\": Invalid ordinal string following '@'") + expectError("999999999999999999999999999999999999999") + expectError("Ordinals must be decimal integers between 0 and 4294967294") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: too big for size of struct) + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x; + int32 y@2; + }; + + ` + expectError("Invalid ordinal for field y: 2.") + expectError("A struct field ordinal must be a non-negative integer value less than the number of fields in the struct.") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: implicit next value too big for size of struct) + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x; + int32 y@2; + int32 z; + }; + + ` + expectError("Invalid ordinal for field z: 3.") + expectError("A struct field ordinal must be a non-negative integer value less than the number of fields in the struct.") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: Duplicate explicit) + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x@0; + int32 y; + int32 z@0; + }; + + ` + expectError("Invalid ordinal for field z: 0.") + expectError("There is already a field in struct MyStruct with that ordinal: x") + endTestCase() + + //////////////////////////////////////////////////////////// + // Test Case (Invalid struct field ordinal: Duplicate implicit) + //////////////////////////////////////////////////////////// + startTestCase("") + cases[testCaseNum].mojomContents = ` + struct MyStruct { + int32 x; + int32 y; + int32 z@1; + }; + + ` + expectError("Invalid ordinal for field z: 1.") + expectError("There is already a field in struct MyStruct with that ordinal: y") + endTestCase() + + //////////////////////////////////////////////////////////// // Test Case (Invalid method ordinal: too big for uint32) //////////////////////////////////////////////////////////// startTestCase("")
diff --git a/mojom/mojom_parser/parser/parsing.go b/mojom/mojom_parser/parser/parsing.go index a8b1128..2fa321a 100644 --- a/mojom/mojom_parser/parser/parsing.go +++ b/mojom/mojom_parser/parser/parsing.go
@@ -654,7 +654,10 @@ } if p.OK() { - paramStruct.ComputeFieldOrdinals() + if err := paramStruct.ComputeFieldOrdinals(); err != nil { + p.err = err + return nil + } } return } @@ -750,8 +753,12 @@ } } if p.OK() { - mojomStruct.ComputeFieldOrdinals() + if err := mojomStruct.ComputeFieldOrdinals(); err != nil { + p.err = err + return false + } } + return p.OK() }
diff --git a/mojom/mojom_parser/parser/resolution_test.go b/mojom/mojom_parser/parser/resolution_test.go index 789374b..8bd7323 100644 --- a/mojom/mojom_parser/parser/resolution_test.go +++ b/mojom/mojom_parser/parser/resolution_test.go
@@ -1045,7 +1045,7 @@ testFunc := func(descriptor *mojom.MojomDescriptor) error { myStructType := descriptor.TypesByKey["TYPE_KEY:MyStruct"].(*mojom.MojomStruct) - aColorField := myStructType.Fields[0] + aColorField := myStructType.FieldsInLexicalOrder[0] concreteValue := aColorField.DefaultValue.ResolvedConcreteValue().(*mojom.EnumValue) key := concreteValue.ValueKey() if key != "TYPE_KEY:Color.BLUE" {
diff --git a/mojom/mojom_parser/serialization/serialization.go b/mojom/mojom_parser/serialization/serialization.go index d4ddff3..502dea4 100644 --- a/mojom/mojom_parser/serialization/serialization.go +++ b/mojom/mojom_parser/serialization/serialization.go
@@ -256,7 +256,7 @@ mojomStruct.DeclData = translateDeclarationData(&s.DeclarationData) mojomStruct.DeclData.ContainedDeclarations = translateContainedDeclarations(&s.NestedDeclarations) - for _, field := range s.Fields { + for _, field := range s.FieldsInOrdinalOrder() { mojomStruct.Fields = append(mojomStruct.Fields, translateStructField(field)) } @@ -611,8 +611,11 @@ } // declaration_order - // TODO(rudominer) DeclarationOrder is currently not populated. - declData.DeclarationOrder = -1 + if d.LexicalPosition() < 0 { + declData.DeclarationOrder = -1 + } else { + declData.DeclarationOrder = d.LexicalPosition() + } // container_type_key containingType := d.ContainingType()
diff --git a/mojom/mojom_parser/serialization/serialization_test.go b/mojom/mojom_parser/serialization/serialization_test.go index 3c543f5..9723a2e 100644 --- a/mojom/mojom_parser/serialization/serialization_test.go +++ b/mojom/mojom_parser/serialization/serialization_test.go
@@ -71,41 +71,61 @@ test.testCaseNum += 1 } -// newShortDeclData constructs a new DeclarationData with the given data. +// newShortDeclDataO constructs a new DeclarationData with the given data. func (test *singleFileTest) newShortDeclData(shortName string) *mojom_types.DeclarationData { declData := test.newContainedDeclData(shortName, "", nil) declData.FullIdentifier = nil return declData } +// newShortDeclDataO constructs a new DeclarationData with the given data. +func (test *singleFileTest) newShortDeclDataO(declarationOrder, declaredOrdinal int32, shortName string) *mojom_types.DeclarationData { + declData := test.newContainedDeclDataA(declarationOrder, declaredOrdinal, shortName, "", nil, nil) + declData.FullIdentifier = nil + return declData +} + // newDeclData constructs a new DeclarationData with the given data. func (test *singleFileTest) newDeclData(shortName, fullIdentifier string) *mojom_types.DeclarationData { return test.newContainedDeclData(shortName, fullIdentifier, nil) } +// newDeclData constructs a new DeclarationData with the given data. +func (test *singleFileTest) newDeclDataO(declarationOrder, declaredOrdinal int32, shortName, fullIdentifier string) *mojom_types.DeclarationData { + return test.newContainedDeclDataA(declarationOrder, declaredOrdinal, shortName, fullIdentifier, nil, nil) +} + // newDeclDataA constructs a new DeclarationData with the given data, including attributes. func (test *singleFileTest) newDeclDataA(shortName, fullIdentifier string, attributes *[]mojom_types.Attribute) *mojom_types.DeclarationData { - return test.newContainedDeclDataA(shortName, fullIdentifier, nil, attributes) + return test.newContainedDeclDataA(-1, -1, shortName, fullIdentifier, nil, attributes) } // newShortDeclDataA constructs a new DeclarationData with the given data, including attributes. func (test *singleFileTest) newShortDeclDataA(shortName string, attributes *[]mojom_types.Attribute) *mojom_types.DeclarationData { - declData := test.newContainedDeclDataA(shortName, "", nil, attributes) + declData := test.newContainedDeclDataA(-1, -1, shortName, "", nil, attributes) + declData.FullIdentifier = nil + return declData +} + +// newShortDeclDataA constructs a new DeclarationData with the given data, including attributes. +func (test *singleFileTest) newShortDeclDataAO(declarationOrder, declaredOrdinal int32, shortName string, + attributes *[]mojom_types.Attribute) *mojom_types.DeclarationData { + declData := test.newContainedDeclDataA(declarationOrder, declaredOrdinal, shortName, "", nil, attributes) declData.FullIdentifier = nil return declData } // newContainedDeclData constructs a new DeclarationData with the given data. func (test *singleFileTest) newContainedDeclData(shortName, fullIdentifier string, containerTypeKey *string) *mojom_types.DeclarationData { - return test.newContainedDeclDataA(shortName, fullIdentifier, containerTypeKey, nil) + return test.newContainedDeclDataA(-1, -1, shortName, fullIdentifier, containerTypeKey, nil) } // newContainedDeclDataA constructs a new DeclarationData with the given data, including attributes. -func (test *singleFileTest) newContainedDeclDataA(shortName, fullIdentifier string, +func (test *singleFileTest) newContainedDeclDataA(declarationOrder, declaredOrdinal int32, shortName, fullIdentifier string, containerTypeKey *string, attributes *[]mojom_types.Attribute) *mojom_types.DeclarationData { - return newContainedDeclDataA(test.fileName(), shortName, fullIdentifier, containerTypeKey, attributes) + return newContainedDeclDataA(declarationOrder, declaredOrdinal, test.fileName(), shortName, fullIdentifier, containerTypeKey, attributes) } // newDeclData constructs a new DeclarationData with the given data. @@ -113,19 +133,24 @@ return newContainedDeclData(fileName, shortName, fullIdentifier, nil) } +// newDeclData constructs a new DeclarationData with the given data. +func newDeclDataO(declarationOrder, declaredOrdinal int32, fileName, shortName, fullIdentifier string) *mojom_types.DeclarationData { + return newContainedDeclDataA(declarationOrder, declaredOrdinal, fileName, shortName, fullIdentifier, nil, nil) +} + // newDeclDataA constructs a new DeclarationData with the given data, including attributes. func newDeclDataA(fileName, shortName, fullIdentifier string, attributes *[]mojom_types.Attribute) *mojom_types.DeclarationData { - return newContainedDeclDataA(fileName, shortName, fullIdentifier, nil, attributes) + return newContainedDeclDataA(-1, -1, fileName, shortName, fullIdentifier, nil, attributes) } // newContainedDeclData constructs a new DeclarationData with the given data. func newContainedDeclData(fileName, shortName, fullIdentifier string, containerTypeKey *string) *mojom_types.DeclarationData { - return newContainedDeclDataA(fileName, shortName, fullIdentifier, containerTypeKey, nil) + return newContainedDeclDataA(-1, -1, fileName, shortName, fullIdentifier, containerTypeKey, nil) } // newContainedDeclDataA constructs a new DeclarationData with the given data, including attributes. -func newContainedDeclDataA(fileName, shortName, fullIdentifier string, +func newContainedDeclDataA(declarationOrder, declaredOrdinal int32, fileName, shortName, fullIdentifier string, containerTypeKey *string, attributes *[]mojom_types.Attribute) *mojom_types.DeclarationData { var fullyQualifiedName *string if fullIdentifier != "" { @@ -135,8 +160,8 @@ Attributes: attributes, ShortName: &shortName, FullIdentifier: fullyQualifiedName, - DeclaredOrdinal: -1, - DeclarationOrder: -1, + DeclaredOrdinal: declaredOrdinal, + DeclarationOrder: declarationOrder, ContainerTypeKey: containerTypeKey, SourceFileInfo: &mojom_types.SourceFileInfo{ FileName: fileName, @@ -149,6 +174,112 @@ test := singleFileTest{} //////////////////////////////////////////////////////////// + // Test Case: struct field ordinals + //////////////////////////////////////////////////////////// + { + + contents := ` + struct Foo{ + int32 x@2; + int32 y@3; + int32 z@0; + int32 w@1; + };` + + test.addTestCase("", contents) + + // DeclaredMojomObjects + test.expectedFile().DeclaredMojomObjects.Structs = &[]string{"TYPE_KEY:Foo"} + + // ResolvedTypes + + // struct Foo + test.expectedGraph().ResolvedTypes["TYPE_KEY:Foo"] = &mojom_types.UserDefinedTypeStructType{mojom_types.MojomStruct{ + DeclData: test.newDeclData("Foo", "Foo"), + Fields: []mojom_types.StructField{ + // The fields are in ordinal order and the first two arguments to newShortDeclDataO() are + // declarationOrder and declaredOrdinal. + + // field z + { + DeclData: test.newShortDeclDataO(2, 0, "z"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + // field w + { + DeclData: test.newShortDeclDataO(3, 1, "w"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + // field x + { + DeclData: test.newShortDeclDataO(0, 2, "x"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + // field y + { + DeclData: test.newShortDeclDataO(1, 3, "y"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + }, + }} + + test.endTestCase() + } + + //////////////////////////////////////////////////////////// + // Test Case: struct field ordinals, some implicit + //////////////////////////////////////////////////////////// + { + + contents := ` + struct Foo{ + int32 x@2; + int32 y; + int32 z@0; + int32 w; + };` + + test.addTestCase("", contents) + + // DeclaredMojomObjects + test.expectedFile().DeclaredMojomObjects.Structs = &[]string{"TYPE_KEY:Foo"} + + // ResolvedTypes + + // struct Foo + test.expectedGraph().ResolvedTypes["TYPE_KEY:Foo"] = &mojom_types.UserDefinedTypeStructType{mojom_types.MojomStruct{ + DeclData: test.newDeclData("Foo", "Foo"), + Fields: []mojom_types.StructField{ + // The fields are in ordinal order and the first two arguments to newShortDeclDataO() are + // declarationOrder and declaredOrdinal. + + // field z + { + DeclData: test.newShortDeclDataO(2, 0, "z"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + // field w + { + DeclData: test.newShortDeclDataO(3, -1, "w"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + // field x + { + DeclData: test.newShortDeclDataO(0, 2, "x"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + // field y + { + DeclData: test.newShortDeclDataO(1, -1, "y"), + Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, + }, + }, + }} + + test.endTestCase() + } + + //////////////////////////////////////////////////////////// // Test Case: array of int32 //////////////////////////////////////////////////////////// { @@ -174,25 +305,25 @@ Fields: []mojom_types.StructField{ // field bar1 is not nullable and not fixed length { - DeclData: test.newShortDeclData("bar1"), + DeclData: test.newShortDeclDataO(0, -1, "bar1"), Type: &mojom_types.TypeArrayType{mojom_types.ArrayType{ false, -1, &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}}}, }, // field bar2 is not nullable and fixed length of 7 { - DeclData: test.newShortDeclData("bar2"), + DeclData: test.newShortDeclDataO(1, -1, "bar2"), Type: &mojom_types.TypeArrayType{mojom_types.ArrayType{ false, 7, &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}}}, }, // field bar3 is nullable and not fixed length { - DeclData: test.newShortDeclData("bar3"), + DeclData: test.newShortDeclDataO(2, -1, "bar3"), Type: &mojom_types.TypeArrayType{mojom_types.ArrayType{ true, -1, &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}}}, }, // field bar4 is nullable and fixed length of 8 { - DeclData: test.newShortDeclData("bar4"), + DeclData: test.newShortDeclDataO(3, -1, "bar4"), Type: &mojom_types.TypeArrayType{mojom_types.ArrayType{ true, 8, &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}}}, }, @@ -228,7 +359,7 @@ Fields: []mojom_types.StructField{ // field bar1 is non-nullable with a non-nullable key. { - DeclData: test.newShortDeclData("bar1"), + DeclData: test.newShortDeclDataO(0, -1, "bar1"), Type: &mojom_types.TypeMapType{mojom_types.MapType{ false, &mojom_types.TypeStringType{mojom_types.StringType{false}}, @@ -236,7 +367,7 @@ }, // field bar2 is non-nullable with a nullable key. { - DeclData: test.newShortDeclData("bar2"), + DeclData: test.newShortDeclDataO(1, -1, "bar2"), Type: &mojom_types.TypeMapType{mojom_types.MapType{ false, &mojom_types.TypeStringType{mojom_types.StringType{true}}, @@ -244,7 +375,7 @@ }, // field bar3 is nullable with a non-nullable key. { - DeclData: test.newShortDeclData("bar3"), + DeclData: test.newShortDeclDataO(2, -1, "bar3"), Type: &mojom_types.TypeMapType{mojom_types.MapType{ true, &mojom_types.TypeStringType{mojom_types.StringType{false}}, @@ -252,7 +383,7 @@ }, // field bar4 is nullable with a nullable key. { - DeclData: test.newShortDeclData("bar4"), + DeclData: test.newShortDeclDataO(3, -1, "bar4"), Type: &mojom_types.TypeMapType{mojom_types.MapType{ true, &mojom_types.TypeStringType{mojom_types.StringType{true}}, @@ -409,7 +540,7 @@ Fields: []mojom_types.StructField{ // field a_color { - DeclData: test.newShortDeclData("a_color"), + DeclData: test.newShortDeclDataO(0, -1, "a_color"), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("Color"), stringPointer("TYPE_KEY:Color")}}, DefaultValue: &mojom_types.DefaultFieldValueValue{&mojom_types.ValueUserValueReference{ @@ -453,7 +584,7 @@ DeclData: test.newDeclData("EchoString-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: test.newDeclData("value", ""), + DeclData: test.newDeclDataO(0, -1, "value", ""), Type: &mojom_types.TypeStringType{mojom_types.StringType{true}}, }, }, @@ -462,7 +593,7 @@ DeclData: test.newDeclData("EchoString-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: test.newDeclData("value", ""), + DeclData: test.newDeclDataO(0, -1, "value", ""), Type: &mojom_types.TypeStringType{mojom_types.StringType{true}}, }, }, @@ -474,11 +605,11 @@ DeclData: test.newDeclData("DelayedEchoString-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: test.newDeclData("value", ""), + DeclData: test.newDeclDataO(0, -1, "value", ""), Type: &mojom_types.TypeStringType{mojom_types.StringType{true}}, }, mojom_types.StructField{ - DeclData: test.newDeclData("millis", ""), + DeclData: test.newDeclDataO(1, -1, "millis", ""), Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, }, }, @@ -487,7 +618,7 @@ DeclData: test.newDeclData("DelayedEchoString-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: test.newDeclData("value", ""), + DeclData: test.newDeclDataO(0, -1, "value", ""), Type: &mojom_types.TypeStringType{mojom_types.StringType{true}}, }, }, @@ -531,7 +662,7 @@ DeclData: test.newDeclData("EchoString-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: test.newDeclData("value", ""), + DeclData: test.newDeclDataO(0, -1, "value", ""), Type: &mojom_types.TypeStringType{mojom_types.StringType{true}}, }, }, @@ -540,7 +671,7 @@ DeclData: test.newDeclData("EchoString-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: test.newDeclData("value", ""), + DeclData: test.newDeclDataO(0, -1, "value", ""), Type: &mojom_types.TypeStringType{mojom_types.StringType{true}}, }, }, @@ -802,18 +933,18 @@ Fields: []mojom_types.StructField{ // field x { - DeclData: test.newShortDeclData("x"), + DeclData: test.newShortDeclDataO(0, -1, "x"), Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32}, }, // field y { - DeclData: test.newShortDeclDataA("y", &[]mojom_types.Attribute{{"min_version", &mojom_types.LiteralValueInt8Value{2}}}), + DeclData: test.newShortDeclDataAO(1, -1, "y", &[]mojom_types.Attribute{{"min_version", &mojom_types.LiteralValueInt8Value{2}}}), Type: &mojom_types.TypeStringType{mojom_types.StringType{false}}, DefaultValue: &mojom_types.DefaultFieldValueValue{&mojom_types.ValueLiteralValue{&mojom_types.LiteralValueStringValue{"hello"}}}, }, // field z { - DeclData: test.newShortDeclData("z"), + DeclData: test.newShortDeclDataO(2, -1, "z"), Type: &mojom_types.TypeStringType{mojom_types.StringType{true}}, }, }, @@ -1385,7 +1516,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1395,7 +1526,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("b.c.d.FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, @@ -1424,7 +1555,7 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("a.b.c.FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1434,7 +1565,7 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, @@ -1500,7 +1631,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1510,7 +1641,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("b.c.d.FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, @@ -1539,7 +1670,7 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("a.b.c.FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1549,7 +1680,7 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, @@ -1620,7 +1751,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1630,7 +1761,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("b.c.d.FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, @@ -1660,7 +1791,7 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("a.b.c.FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1670,7 +1801,7 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, @@ -1741,7 +1872,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1751,7 +1882,7 @@ DeclData: newDeclData(test.fileNameA(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameA(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameA(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("b.c.d.FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, @@ -1782,7 +1913,7 @@ DeclData: newDeclData(test.fileNameB(), "FooB", "b.c.d.FooB"), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("Enum1"), stringPointer("TYPE_KEY:b.c.d.Enum1")}}, }, @@ -1799,7 +1930,7 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-request", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "x", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "x", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("a.b.c.FooA"), stringPointer("TYPE_KEY:a.b.c.FooA")}}, }, @@ -1809,12 +1940,12 @@ DeclData: newDeclData(test.fileNameB(), "DoIt-response", ""), Fields: []mojom_types.StructField{ mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "y", ""), + DeclData: newDeclDataO(0, -1, test.fileNameB(), "y", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ true, false, stringPointer("FooB"), stringPointer("TYPE_KEY:b.c.d.FooB")}}, }, mojom_types.StructField{ - DeclData: newDeclData(test.fileNameB(), "z", ""), + DeclData: newDeclDataO(1, -1, test.fileNameB(), "z", ""), Type: &mojom_types.TypeTypeReference{mojom_types.TypeReference{ false, false, stringPointer("Enum2"), stringPointer("TYPE_KEY:b.c.d.Enum2")}}, },