| Index: src/parsing/parser-base.h
|
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
| index 66138b70d63d54b94f226c4af55f8d9c83d91048..335a7453100b8a43802ecbc4b6d3621739f17535 100644
|
| --- a/src/parsing/parser-base.h
|
| +++ b/src/parsing/parser-base.h
|
| @@ -749,6 +749,7 @@ class ParserBase : public Traits {
|
| ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
|
| bool* is_computed_name,
|
| ExpressionClassifier* classifier, bool* ok);
|
| + ExpressionT ParsePropertyNameInType(bool* ok);
|
| ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
|
| ObjectLiteralPropertyT ParsePropertyDefinition(
|
| ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
|
| @@ -844,6 +845,7 @@ class ParserBase : public Traits {
|
| typename TypeSystem::TypeParameters ParseTypeParameters(bool* ok);
|
| typename TypeSystem::TypeList ParseTypeArguments(bool* ok);
|
| IdentifierListT ParsePropertyNameList(bool* ok);
|
| + typename TypeSystem::TypeMember ParseTypeMember(bool* ok);
|
|
|
| typename TypeSystem::Type ValidateType(typename TypeSystem::Type type,
|
| Scanner::Location location, bool* ok) {
|
| @@ -1593,6 +1595,51 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
|
| }
|
|
|
|
|
| +// This is a simplified version of ParsePropertyName
|
| +template <class Traits>
|
| +typename ParserBase<Traits>::ExpressionT
|
| +ParserBase<Traits>::ParsePropertyNameInType(bool* ok) {
|
| + Token::Value token = peek();
|
| + int pos = peek_position();
|
| + IdentifierT name = this->EmptyIdentifier();
|
| +
|
| + // For non computed property names we normalize the name a bit:
|
| + //
|
| + // "12" -> 12
|
| + // 12.3 -> "12.3"
|
| + // 12.30 -> "12.3"
|
| + // identifier -> "identifier"
|
| + //
|
| + // This is important because we use the property name as a key in a hash
|
| + // table when we compute constant properties.
|
| + switch (token) {
|
| + case Token::STRING:
|
| + Consume(Token::STRING);
|
| + name = this->GetSymbol(scanner());
|
| + break;
|
| +
|
| + case Token::SMI:
|
| + Consume(Token::SMI);
|
| + name = this->GetNumberAsSymbol(scanner());
|
| + break;
|
| +
|
| + case Token::NUMBER:
|
| + Consume(Token::NUMBER);
|
| + name = this->GetNumberAsSymbol(scanner());
|
| + break;
|
| +
|
| + default:
|
| + name = ParseIdentifierName(CHECK_OK);
|
| + break;
|
| + }
|
| +
|
| + uint32_t index;
|
| + return this->IsArrayIndex(name, &index)
|
| + ? factory()->NewNumberLiteral(index, pos)
|
| + : factory()->NewStringLiteral(name, pos);
|
| +}
|
| +
|
| +
|
| template <class Traits>
|
| typename ParserBase<Traits>::ObjectLiteralPropertyT
|
| ParserBase<Traits>::ParsePropertyDefinition(
|
| @@ -3328,7 +3375,7 @@ ParserBase<Traits>::ParsePrimaryTypeOrParameterList(bool* ok) {
|
| if (!type_element->IsValidType()) valid_type = false;
|
| if (!type_element->IsValidBindingIdentifierOrPattern())
|
| valid_binder = false;
|
| - if (peek() != Token::RBRACK) { // Braces required here.
|
| + if (peek() != Token::RBRACK) {
|
| Expect(Token::COMMA, CHECK_OK_TYPE);
|
| trailing_comma = true;
|
| }
|
| @@ -3339,6 +3386,26 @@ ParserBase<Traits>::ParsePrimaryTypeOrParameterList(bool* ok) {
|
| valid_binder, spread, pos);
|
| break;
|
| }
|
| + case Token::LBRACE: {
|
| + Consume(Token::LBRACE);
|
| + typename TypeSystem::TypeMembers members = this->EmptyTypeMembers();
|
| + bool valid_type = true, valid_binder = true;
|
| + while (peek() != Token::RBRACE) {
|
| + typename TypeSystem::TypeMember type_member =
|
| + ParseTypeMember(CHECK_OK_TYPE);
|
| + members->Add(type_member, zone());
|
| + if (!type_member->IsValidType()) valid_type = false;
|
| + if (!type_member->IsValidBindingIdentifierOrPattern())
|
| + valid_binder = false;
|
| + if (peek() != Token::RBRACE && !Check(Token::COMMA)) {
|
| + ExpectSemicolon(CHECK_OK_TYPE);
|
| + valid_binder = false; // Semicolons not allowed in valid binders.
|
| + }
|
| + }
|
| + Consume(Token::RBRACE);
|
| + type = factory()->NewObjectType(members, valid_type, valid_binder, pos);
|
| + break;
|
| + }
|
| case Token::TYPEOF: {
|
| Consume(Token::TYPEOF);
|
| IdentifierT name = ParseIdentifierName(CHECK_OK_TYPE);
|
| @@ -3360,7 +3427,6 @@ ParserBase<Traits>::ParsePrimaryTypeOrParameterList(bool* ok) {
|
| type = factory()->NewThisType(pos);
|
| break;
|
| }
|
| - // TODO(nikolaos): Missing object types.
|
| case Token::STRING: {
|
| Consume(Token::STRING);
|
| IdentifierT str = this->GetSymbol(scanner());
|
| @@ -3401,6 +3467,91 @@ ParserBase<Traits>::ParsePropertyNameList(bool* ok) {
|
| }
|
|
|
|
|
| +template <typename Traits>
|
| +typename ParserBase<Traits>::TypeSystem::TypeMember
|
| +ParserBase<Traits>::ParseTypeMember(bool* ok) {
|
| + int pos = peek_position();
|
| + bool valid_type = true, valid_binder = false;
|
| + // Parse index signature.
|
| + if (Check(Token::LBRACK)) {
|
| + int property_pos = peek_position();
|
| + IdentifierT property_name =
|
| + ParseIdentifierName(CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + ExpressionT property =
|
| + factory()->NewStringLiteral(property_name, property_pos);
|
| + Expect(Token::COLON, CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + typesystem::TypeMember::IndexType index_type =
|
| + typesystem::TypeMember::kNoIndexType;
|
| + if (peek() == Token::IDENTIFIER) {
|
| + if (CheckContextualKeyword(CStrVector("number"))) {
|
| + index_type = typesystem::TypeMember::kNumberIndexType;
|
| + } else if (CheckContextualKeyword(CStrVector("string"))) {
|
| + index_type = typesystem::TypeMember::kStringIndexType;
|
| + }
|
| + }
|
| + if (index_type == typesystem::TypeMember::kNoIndexType) {
|
| + Scanner::Location next_location = scanner()->peek_location();
|
| + ReportMessageAt(next_location, MessageTemplate::kBadIndexType);
|
| + *ok = false;
|
| + return this->EmptyTypeMember();
|
| + }
|
| + Expect(Token::RBRACK, CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + // Parse optional result type
|
| + typename TypeSystem::Type type = this->EmptyType();
|
| + if (Check(Token::COLON)) { // Braces required here.
|
| + type = ParseValidType(CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + }
|
| + return factory()->NewTypeMember(property, index_type, type, pos);
|
| + }
|
| + // Parse property, method, call or constructor signatures.
|
| + ExpressionT property = this->EmptyExpression();
|
| + bool has_property = false;
|
| + bool optional = false;
|
| + bool has_new = Check(Token::NEW);
|
| + if (!has_new && peek() != Token::LT && peek() != Token::LPAREN) {
|
| + // Parse property name.
|
| + property = ParsePropertyNameInType(CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + has_property = true;
|
| + optional = Check(Token::CONDITIONAL);
|
| + valid_binder = !optional;
|
| + }
|
| + // Parse optional type parameters.
|
| + typename TypeSystem::TypeParameters type_parameters =
|
| + this->NullTypeParameters();
|
| + if (peek() == Token::LT) { // Braces required here.
|
| + type_parameters = ParseTypeParameters(CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + valid_binder = false;
|
| + }
|
| + // Require formal parameters if type parameters are present
|
| + // or if no property was specified.
|
| + if ((!has_property || !this->IsNullTypeParameters(type_parameters)) &&
|
| + peek() != Token::LPAREN) {
|
| + Expect(Token::LPAREN, CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + UNREACHABLE();
|
| + }
|
| + // Parse optional formal parameters.
|
| + typename TypeSystem::FormalParameters parameters =
|
| + this->NullFormalParameters();
|
| + if (peek() == Token::LPAREN) {
|
| + typename TypeSystem::Type type_params =
|
| + ParsePrimaryTypeOrParameterList(CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + parameters = type_params->AsValidParameterList(
|
| + zone_, CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + valid_binder = false;
|
| + }
|
| + // Parse optional property or result type or covered binding pattern.
|
| + typename TypeSystem::Type type = this->EmptyType();
|
| + if (Check(Token::COLON)) {
|
| + type = ParseType(CHECK_OK_CUSTOM(EmptyTypeMember));
|
| + if (!type->IsValidType()) valid_type = false;
|
| + if (!type->IsValidBindingIdentifierOrPattern()) valid_binder = false;
|
| + }
|
| + return factory()->NewTypeMember(property, optional, type_parameters,
|
| + parameters, type, valid_type, valid_binder,
|
| + pos, has_new);
|
| +}
|
| +
|
| +
|
| #undef CHECK_OK
|
| #undef CHECK_OK_CUSTOM
|
| #undef CHECK_OK_TYPE
|
|
|