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

Unified Diff: src/parsing/parser.cc

Issue 2112223002: Revert of Add errors for declarations which conflict with catch parameters. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « src/ast/scopes.cc ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/parser.cc
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc
index 0192f11d85bc3a377512343fb69ac052c0640221..24df10cb9d7a4021d1541c90c77e09caee97ed6a 100644
--- a/src/parsing/parser.cc
+++ b/src/parsing/parser.cc
@@ -1929,10 +1929,11 @@
VariableProxy* Parser::NewUnresolved(const AstRawString* name,
VariableMode mode) {
- // If we are inside a function, a declaration of a 'var' variable is a
+ // If we are inside a function, a declaration of a var/const variable is a
// truly local variable, and the scope of the variable is always the function
// scope.
- // Let/const variables are always added to the immediately enclosing scope.
+ // Let/const variables in harmony mode are always added to the immediately
+ // enclosing scope.
Scope* scope =
IsLexicalVariableMode(mode) ? scope_ : scope_->DeclarationScope();
return scope->NewUnresolved(factory(), name, Variable::NORMAL,
@@ -2325,11 +2326,11 @@
// VariableStatement ::
// VariableDeclarations ';'
- // The scope of a var declared variable anywhere inside a function
+ // The scope of a var/const declared variable anywhere inside a function
// is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
- // transform a source-level var declaration into a (Function) Scope
- // declaration, and rewrite the source-level initialization into an assignment
- // statement. We use a block to collect multiple assignments.
+ // transform a source-level var/const declaration into a (Function)
+ // Scope declaration, and rewrite the source-level initialization into an
+ // assignment statement. We use a block to collect multiple assignments.
//
// We mark the block as initializer block because we don't want the
// rewriter to add a '.result' assignment to such a block (to get compliant
@@ -3027,8 +3028,6 @@
Expect(Token::RPAREN, CHECK_OK);
- ZoneList<const AstRawString*> bound_names(1, zone());
-
if (!is_simple) {
DeclarationDescriptor descriptor;
descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
@@ -3046,34 +3045,20 @@
Block* init_block =
factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
PatternRewriter::DeclareAndInitializeVariables(
- init_block, &descriptor, &decl, &bound_names, CHECK_OK);
+ init_block, &descriptor, &decl, nullptr, CHECK_OK);
catch_block->statements()->Add(init_block, zone());
- } else {
- bound_names.Add(name, zone());
}
- Block* inner_block = ParseBlock(nullptr, CHECK_OK);
- catch_block->statements()->Add(inner_block, zone());
-
- // Check for `catch(e) { let e; }` and similar errors.
- Scope* inner_block_scope = inner_block->scope();
- if (inner_block_scope != nullptr) {
- Declaration* decl =
- inner_block_scope->CheckLexDeclarationsConflictingWith(
- &bound_names);
- if (decl != nullptr) {
- const AstRawString* name = decl->proxy()->raw_name();
- int position = decl->proxy()->position();
- Scanner::Location location =
- position == kNoSourcePosition
- ? Scanner::Location::invalid()
- : Scanner::Location(position, position + 1);
- ParserTraits::ReportMessageAt(
- location, MessageTemplate::kVarRedeclaration, name);
- *ok = false;
- return nullptr;
+ // TODO(adamk): This should call ParseBlock in order to properly
+ // add an additional block scope for the catch body.
+ Expect(Token::LBRACE, CHECK_OK);
+ while (peek() != Token::RBRACE) {
+ Statement* stat = ParseStatementListItem(CHECK_OK);
+ if (stat && !stat->IsEmpty()) {
+ catch_block->statements()->Add(stat, zone());
}
}
+ Consume(Token::RBRACE);
}
block_scope->set_end_position(scanner()->location().end_pos);
block_scope = block_scope->FinalizeBlockScope();
@@ -3573,8 +3558,7 @@
bool* ok) {
int stmt_pos = peek_position();
Statement* init = NULL;
- ZoneList<const AstRawString*> bound_names(1, zone());
- bool bound_names_are_lexical = false;
+ ZoneList<const AstRawString*> lexical_bindings(1, zone());
// Create an in-between scope for let-bound iteration variables.
Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
@@ -3625,12 +3609,10 @@
}
Block* init_block = nullptr;
- bound_names_are_lexical =
- IsLexicalVariableMode(parsing_result.descriptor.mode);
-
- // special case for legacy for (var ... = ... in ...)
- if (!bound_names_are_lexical && decl.pattern->IsVariableProxy() &&
- decl.initializer != nullptr) {
+
+ // special case for legacy for (var/const x =.... in)
+ if (!IsLexicalVariableMode(parsing_result.descriptor.mode) &&
+ decl.pattern->IsVariableProxy() && decl.initializer != nullptr) {
DCHECK(!allow_harmony_for_in());
++use_counts_[v8::Isolate::kForInInitializer];
const AstRawString* name =
@@ -3703,44 +3685,11 @@
descriptor.initialization_pos = kNoSourcePosition;
decl.initializer = factory()->NewVariableProxy(temp);
- bool is_for_var_of =
- mode == ForEachStatement::ITERATE &&
- parsing_result.descriptor.mode == VariableMode::VAR;
-
PatternRewriter::DeclareAndInitializeVariables(
each_initialization_block, &descriptor, &decl,
- bound_names_are_lexical || is_for_var_of ? &bound_names
- : nullptr,
+ IsLexicalVariableMode(descriptor.mode) ? &lexical_bindings
+ : nullptr,
CHECK_OK);
-
- // Annex B.3.5 prohibits the form
- // `try {} catch(e) { for (var e of {}); }`
- // So if we are parsing a statement like `for (var ... of ...)`
- // we need to walk up the scope chain and look for catch scopes
- // which have a simple binding, then compare their binding against
- // all of the names declared in the init of the for-of we're
- // parsing.
- if (is_for_var_of) {
- Scope* catch_scope = scope_;
- while (catch_scope != nullptr &&
- !catch_scope->is_declaration_scope()) {
- if (catch_scope->is_catch_scope()) {
- auto name = catch_scope->catch_variable_name();
- if (name !=
- ast_value_factory()
- ->dot_catch_string()) { // i.e. is a simple binding
- if (bound_names.Contains(name)) {
- ParserTraits::ReportMessageAt(
- parsing_result.bindings_loc,
- MessageTemplate::kVarRedeclaration, name);
- *ok = false;
- return nullptr;
- }
- }
- }
- catch_scope = catch_scope->outer_scope();
- }
- }
}
body_block->statements()->Add(each_initialization_block, zone());
@@ -3755,17 +3704,18 @@
body_block->set_scope(body_scope);
// Create a TDZ for any lexically-bound names.
- if (bound_names_are_lexical) {
+ if (IsLexicalVariableMode(parsing_result.descriptor.mode)) {
DCHECK_NULL(init_block);
init_block =
factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
- for (int i = 0; i < bound_names.length(); ++i) {
+ for (int i = 0; i < lexical_bindings.length(); ++i) {
// TODO(adamk): This needs to be some sort of special
// INTERNAL variable that's invisible to the debugger
// but visible to everything else.
- VariableProxy* tdz_proxy = NewUnresolved(bound_names[i], LET);
+ VariableProxy* tdz_proxy =
+ NewUnresolved(lexical_bindings[i], LET);
Declaration* tdz_decl = factory()->NewVariableDeclaration(
tdz_proxy, LET, scope_, kNoSourcePosition);
Variable* tdz_var = Declare(
@@ -3792,10 +3742,11 @@
return final_loop;
}
} else {
- bound_names_are_lexical =
- IsLexicalVariableMode(parsing_result.descriptor.mode);
init = parsing_result.BuildInitializationBlock(
- bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK);
+ IsLexicalVariableMode(parsing_result.descriptor.mode)
+ ? &lexical_bindings
+ : nullptr,
+ CHECK_OK);
}
} else {
int lhs_beg_pos = peek_position();
@@ -3876,7 +3827,7 @@
// If there are let bindings, then condition and the next statement of the
// for loop must be parsed in a new scope.
Scope* inner_scope = scope_;
- if (bound_names_are_lexical && bound_names.length() > 0) {
+ if (lexical_bindings.length() > 0) {
inner_scope = NewScope(for_scope, BLOCK_SCOPE);
inner_scope->set_start_position(scanner()->location().beg_pos);
}
@@ -3898,11 +3849,11 @@
}
Statement* result = NULL;
- if (bound_names_are_lexical && bound_names.length() > 0) {
+ if (lexical_bindings.length() > 0) {
BlockState block_state(&scope_, for_scope);
result = DesugarLexicalBindingsInForStatement(
- inner_scope, parsing_result.descriptor.mode, &bound_names, loop, init,
- cond, next, body, CHECK_OK);
+ inner_scope, parsing_result.descriptor.mode, &lexical_bindings, loop,
+ init, cond, next, body, CHECK_OK);
for_scope->set_end_position(scanner()->location().end_pos);
} else {
for_scope->set_end_position(scanner()->location().end_pos);
« no previous file with comments | « src/ast/scopes.cc ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698