Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Unified Diff: src/parsing/parser-base.h

Issue 1817093002: Add parsing for object types (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@types-1810943002-tuple
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/parsing/parser-base.h
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
index 66138b70d63d54b94f226c4af55f8d9c83d91048..90889042849ab42001710e7fe66b208b99362af3 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,89 @@ 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 no property was specified.
+ if (!has_property && 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

Powered by Google App Engine
This is Rietveld 408576698