Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 7fc5dd0512b4ba73be38148b35a9faaffc63be8a..5d3d14d8c7940c2724f5027852ee97bc40af41a2 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -694,14 +694,6 @@ Expression* ParserTraits::SuperReference( |
pos); |
} |
-Expression* ParserTraits::ClassExpression( |
- const AstRawString* name, Expression* extends, Expression* constructor, |
- ZoneList<ObjectLiteral::Property*>* properties, int start_position, |
- int end_position, AstNodeFactory<AstConstructionVisitor>* factory) { |
- return factory->NewClassLiteral(name, extends, constructor, properties, |
- start_position, end_position); |
-} |
- |
Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope, |
int pos, int end_pos) { |
@@ -789,6 +781,14 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
} |
+ClassLiteral* ParserTraits::ParseClassLiteral( |
+ const AstRawString* name, Scanner::Location class_name_location, |
+ bool name_is_strict_reserved, int pos, bool* ok) { |
+ return parser_->ParseClassLiteral(name, class_name_location, |
+ name_is_strict_reserved, pos, ok); |
+} |
+ |
+ |
Parser::Parser(CompilationInfo* info, ParseInfo* parse_info) |
: ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit, |
info->extension(), NULL, info->zone(), this), |
@@ -2011,8 +2011,8 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, |
bool is_strict_reserved = false; |
const AstRawString* name = |
ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
- Expression* value = ParseClassLiteral(name, scanner()->location(), |
- is_strict_reserved, pos, CHECK_OK); |
+ ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), |
+ is_strict_reserved, pos, CHECK_OK); |
VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue()); |
Declaration* declaration = |
@@ -3919,6 +3919,94 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
} |
+ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, |
arv (Not doing code reviews)
2014/11/12 23:15:41
I had to split the code from ParserBase into Parse
|
+ Scanner::Location class_name_location, |
+ bool name_is_strict_reserved, int pos, |
+ bool* ok) { |
+ // All parts of a ClassDeclaration and ClassExpression are strict code. |
+ if (name_is_strict_reserved) { |
+ ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
+ *ok = false; |
+ return NULL; |
+ } |
+ if (this->IsEvalOrArguments(name)) { |
adamk
2014/11/13 01:45:43
I don't think you need these explicit |this| refer
arv (Not doing code reviews)
2014/11/13 20:47:50
Done.
|
+ ReportMessageAt(class_name_location, "strict_eval_arguments"); |
+ *ok = false; |
+ return NULL; |
+ } |
+ |
+ Scope* block_scope = this->NewScope(scope_, BLOCK_SCOPE); |
+ BlockState block_state(&scope_, block_scope); |
+ scope_->SetStrictMode(STRICT); |
+ scope_->SetScopeName(name); |
+ |
+ VariableProxy* proxy = NULL; |
+ if (name != NULL) { |
+ proxy = NewUnresolved(name, CONST, Interface::NewConst()); |
+ Declaration* declaration = |
+ factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos); |
+ Declare(declaration, true, CHECK_OK); |
+ } |
+ |
+ bool has_extends = false; |
+ Expression* extends = NULL; |
+ if (Check(Token::EXTENDS)) { |
+ block_scope->set_start_position(scanner()->location().end_pos); |
+ extends = this->ParseLeftHandSideExpression(CHECK_OK); |
+ has_extends = true; |
+ } else { |
+ block_scope->set_start_position(scanner()->location().end_pos); |
+ } |
+ |
+ ZoneList<ObjectLiteral::Property*>* properties = |
+ this->NewPropertyList(4, zone()); |
+ Expression* constructor = NULL; |
+ bool has_seen_constructor = false; |
+ |
+ Expect(Token::LBRACE, CHECK_OK); |
+ while (peek() != Token::RBRACE) { |
+ if (Check(Token::SEMICOLON)) continue; |
+ if (fni_ != NULL) fni_->Enter(); |
+ const bool in_class = true; |
+ const bool is_static = false; |
+ bool old_has_seen_constructor = has_seen_constructor; |
+ ObjectLiteral::Property* property = this->ParsePropertyDefinition( |
+ NULL, in_class, is_static, &has_seen_constructor, CHECK_OK); |
+ |
+ if (has_seen_constructor != old_has_seen_constructor) { |
Dmitry Lomov (no reviews)
2014/11/13 11:17:37
Nit: replace this condition with 'constructor == N
arv (Not doing code reviews)
2014/11/13 20:47:49
Done.
|
+ constructor = this->GetPropertyValue(property); |
+ } else { |
+ properties->Add(property, zone()); |
+ } |
+ |
+ if (fni_ != NULL) { |
+ fni_->Infer(); |
+ fni_->Leave(); |
+ } |
+ } |
+ |
+ Expect(Token::RBRACE, CHECK_OK); |
+ int end_pos = scanner()->location().end_pos; |
+ |
+ if (!has_seen_constructor) { |
Dmitry Lomov (no reviews)
2014/11/13 11:17:37
Nit: replace this condition with 'constructor == N
arv (Not doing code reviews)
2014/11/13 20:47:50
Done.
|
+ constructor = |
+ this->DefaultConstructor(has_extends, block_scope, pos, end_pos); |
+ } |
+ |
+ block_scope->set_end_position(end_pos); |
+ block_scope = block_scope->FinalizeBlockScope(); |
+ |
+ if (name != NULL) { |
+ DCHECK_NOT_NULL(proxy); |
+ DCHECK_NOT_NULL(block_scope); |
+ proxy->var()->set_initializer_position(end_pos); |
+ } |
+ |
+ return factory()->NewClassLiteral(name, block_scope, proxy, extends, |
+ constructor, properties, pos, end_pos); |
+} |
+ |
+ |
Expression* Parser::ParseV8Intrinsic(bool* ok) { |
// CallRuntime :: |
// '%' Identifier Arguments |