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

Unified Diff: src/parser.cc

Issue 722793005: Classes: Implement correct name binding (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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/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

Powered by Google App Engine
This is Rietveld 408576698