// STRUCT_FIELD -> TYPE name [ordinal] [equals DEFAULT_VALUE] semi // DEFAULT_VALUE -> APPROPRIATE_VAL_SPEC | default // APPROPRIATE_VAL_SPEC -> VALUE_REF {{that resolves to a type that is assignment compatible to the type of the assignee}} func (p *Parser) parseStructField(attributes *mojom.Attributes) *mojom.StructField { if !p.OK() { return nil } p.pushChildNode("structField") defer p.popNode() fieldType := p.parseType() fieldName := p.readName() nameToken := p.lastConsumed p.attachToken() ordinalValue, err := p.readOrdinal() if err != nil { p.err = p.newInvalidOrdinalError("field", fieldName, nameToken, err) return nil } var defaultValue mojom.ValueRef var defaultValueToken lexer.Token if p.tryMatch(lexer.Equals) { defaultValueToken = p.peekNextToken("Expecting a default value.") if defaultValueToken.Kind == lexer.Default { p.consumeNextToken() defaultValue = mojom.MakeDefaultLiteral() } else { defaultValue = p.parseValue(fieldType) } } if !p.matchSemicolon() { return nil } declData := p.DeclDataWithOrdinal(fieldName, nameToken, attributes, ordinalValue) field := mojom.NewStructField(declData, fieldType, defaultValue) if !field.ValidateDefaultValue() { valueString := fmt.Sprintf("%v", defaultValue) valueTypeString := "" concreteValue := defaultValue.ResolvedConcreteValue() if concreteValue != nil { valueString = fmt.Sprintf("%v", concreteValue.Value()) valueTypeString = fmt.Sprintf(" of type %s", concreteValue.ValueType()) } message := fmt.Sprintf("Illegal assignment at %s: Field %s of type %s may not be assigned the value %v%s.", defaultValueToken.LongLocationString(), fieldName, fieldType, valueString, valueTypeString) p.err = &ParseError{ParserErrorCodeNotAssignmentCompatible, message} return nil } return field }
func translateDefaultFieldValue(v mojom.ValueRef) mojom_types.DefaultFieldValue { switch v := v.(type) { case mojom.LiteralValue: if v.IsDefault() { return &mojom_types.DefaultFieldValueDefaultKeyword{mojom_types.DefaultKeyword{}} } return &mojom_types.DefaultFieldValueValue{translateLiteralValue(v)} case *mojom.UserValueRef: return &mojom_types.DefaultFieldValueValue{translateUserValueRef(v)} default: panic(fmt.Sprintf("Unexpected ValueRef type: %T", v)) } }
// STRUCT_FIELD -> TYPE name [ordinal] [equals DEFAULT_VALUE] semi // DEFAULT_VALUE -> APPROPRIATE_VAL_SPEC | default // APPROPRIATE_VAL_SPEC -> VALUE_REF {{that resolves to a type that is assignment compatible to the type of the assignee}} func (p *Parser) parseStructField(attributes *mojom.Attributes) *mojom.StructField { if !p.OK() { return nil } p.pushChildNode("structField") defer p.popNode() fieldType := p.parseType() fieldName := p.readName() p.attachToken() ordinalValue := p.readOrdinal() var defaultValue mojom.ValueRef var defaultValueToken lexer.Token if p.tryMatch(lexer.EQUALS) { defaultValueToken = p.peekNextToken("Expecting a default value.") if defaultValueToken.Kind == lexer.DEFAULT { p.consumeNextToken() defaultValue = mojom.MakeDefaultLiteral() } else { defaultValue = p.parseValue(fieldType) } } if !p.matchSemicolon() { return nil } field := mojom.NewStructField(fieldType, fieldName, ordinalValue, attributes, defaultValue) if !field.ValidateDefaultValue() { valueString := fmt.Sprintf("%v", defaultValue) valueTypeString := "" concreteValue := defaultValue.ResolvedConcreteValue() if concreteValue != nil { valueString = fmt.Sprintf("%v", concreteValue.Value()) valueTypeString = fmt.Sprintf(" of type %s", concreteValue.ValueType()) } message := fmt.Sprintf("Illegal assignment at %s: Field %s of type %s may not be assigned the value %v%s.", defaultValueToken.LongLocationString(), fieldName, fieldType, valueString, valueTypeString) p.err = &ParseError{E_TYPE_NOT_ASSIGNMENT_COMPATIBLE, message} return nil } return field }