Example #1
0
// MAP_TYPE      -> map langle MAP_KEY_TYPE comma TYPE rangle [qstn]
// MAP_KEY_TYPE  -> SIMPLE_TYPE | string | ENUM_TYPE
func (p *Parser) tryParseMapType() mojom.TypeRef {
	if !p.OK() {
		return nil
	}

	nextToken := p.peekNextToken("Trying to read a type.")
	if nextToken.Kind != lexer.Name || nextToken.Text != "map" {
		return nil
	}
	p.consumeNextToken()
	if !p.match(lexer.LAngle) {
		return nil
	}

	keyToken := p.peekNextToken("Trying to read a type.")
	keyType := p.parseType()
	p.match(lexer.Comma)
	valueType := p.parseType()
	if !p.match(lexer.RAngle) {
		return nil
	}
	nullable := p.tryMatch(lexer.Qstn)

	if !keyType.MarkUsedAsMapKey() {
		message := fmt.Sprintf("The type %s at %s is not allowed as the key "+
			"type of a map. Only simple types, strings and enum types may "+
			"be map keys.",
			keyType, keyToken.LongLocationString())
		p.err = &ParseError{ParserErrorCodeUnexpectedToken, message}
		return nil
	}

	return mojom.NewMapTypeRef(keyType, valueType, nullable)
}
Example #2
0
// MAP_TYPE      -> map langle MAP_KEY_TYPE comma TYPE rangle [qstn]
// MAP_KEY_TYPE  -> SIMPLE_TYPE | string | ENUM_TYPE
func (p *Parser) tryReadMapType() mojom.TypeRef {
	if !p.OK() {
		return nil
	}

	nextToken := p.peekNextToken("Trying to read a type.")
	if nextToken.Kind != lexer.NAME || nextToken.Text != "map" {
		return nil
	}
	p.consumeNextToken()
	if !p.match(lexer.LANGLE) {
		return nil
	}

	keyToken := p.peekNextToken("Trying to read a type.")
	keyType := p.parseType()
	p.match(lexer.COMMA)
	valueType := p.parseType()
	if !p.match(lexer.RANGLE) {
		return nil
	}
	nullable := p.tryMatch(lexer.QSTN)

	if !keyType.MarkUsedAsMapKey() {
		message := fmt.Sprintf("The type %s at %s is not allowed as the key "+
			"type of a map. Only simple types, strings and enum types may "+
			"be map keys.",
			keyType, keyToken.LongLocationString())
		p.err = &ParseError{E_UNEXPECTED_TOKEN, message}
		return nil
	}

	return mojom.NewMapTypeRef(keyType, valueType, nullable)
}