| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index a45a4b15e60c906256719822d08ae8f2b16921b1..fb63c6ac75bb754be1904b8ec4bf8e36599f9ddd 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -1554,7 +1554,7 @@ ZoneList<ImportDeclaration*>* Parser::ParseNamedImports(int pos, bool* ok) {
|
| VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
|
| ImportDeclaration* declaration =
|
| factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
|
| + Declare(declaration, DeclarationDescriptor::NORMAL, true, true, CHECK_OK);
|
| result->Add(declaration, zone());
|
| if (peek() == Token::RBRACE) break;
|
| Expect(Token::COMMA, CHECK_OK);
|
| @@ -1603,7 +1603,7 @@ Statement* Parser::ParseImportDeclaration(bool* ok) {
|
| import_default_declaration = factory()->NewImportDeclaration(
|
| proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
|
| Declare(import_default_declaration, DeclarationDescriptor::NORMAL, true,
|
| - CHECK_OK);
|
| + true, CHECK_OK);
|
| }
|
|
|
| const AstRawString* module_instance_binding = NULL;
|
| @@ -1992,7 +1992,7 @@ VariableProxy* Parser::NewUnresolved(const AstRawString* name,
|
|
|
| Variable* Parser::Declare(Declaration* declaration,
|
| DeclarationDescriptor::Kind declaration_kind,
|
| - bool resolve, bool* ok) {
|
| + bool resolve, bool report_error, bool* ok) {
|
| VariableProxy* proxy = declaration->proxy();
|
| DCHECK(proxy->raw_name() != NULL);
|
| const AstRawString* name = proxy->raw_name();
|
| @@ -2051,10 +2051,13 @@ Variable* Parser::Declare(Declaration* declaration,
|
| if (is_strict(language_mode()) || allow_harmony_sloppy()) {
|
| // In harmony we treat re-declarations as early errors. See
|
| // ES5 16 for a definition of early errors.
|
| - if (declaration_kind == DeclarationDescriptor::NORMAL) {
|
| - ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration, name);
|
| - } else {
|
| - ParserTraits::ReportMessage(MessageTemplate::kStrictParamDupe);
|
| + if (report_error) {
|
| + if (declaration_kind == DeclarationDescriptor::NORMAL) {
|
| + ParserTraits::ReportMessage(MessageTemplate::kVarRedeclaration,
|
| + name);
|
| + } else {
|
| + ParserTraits::ReportMessage(MessageTemplate::kStrictParamDupe);
|
| + }
|
| }
|
| *ok = false;
|
| return nullptr;
|
| @@ -2169,7 +2172,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
| VariableProxy* proxy = NewUnresolved(name, VAR);
|
| Declaration* declaration =
|
| factory()->NewVariableDeclaration(proxy, VAR, scope_, pos);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
|
| + Declare(declaration, DeclarationDescriptor::NORMAL, true, true, CHECK_OK);
|
| NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral(
|
| name, extension_, RelocInfo::kNoPosition);
|
| return factory()->NewExpressionStatement(
|
| @@ -2216,8 +2219,33 @@ Statement* Parser::ParseFunctionDeclaration(
|
| VariableProxy* proxy = NewUnresolved(name, mode);
|
| Declaration* declaration =
|
| factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
|
| + Declare(declaration, DeclarationDescriptor::NORMAL, true, true, CHECK_OK);
|
| if (names) names->Add(name, zone());
|
| +
|
| + // For sloppy function in block we also add a var binding that gets assigned
|
| + // to at the location of the FunctionDeclaration -- but only if introducing
|
| + // this var binding does not lead to an early error.
|
| + if (is_sloppy(language_mode()) && scope_->is_block_scope() &&
|
| + allow_harmony_sloppy()) {
|
| + VariableProxy* var_proxy = NewUnresolved(name, VAR);
|
| + Declaration* declaration =
|
| + factory()->NewVariableDeclaration(var_proxy, VAR, scope_, pos);
|
| + bool var_ok = true;
|
| + const bool resolve = true;
|
| + const bool report_error = false;
|
| + Declare(declaration, DeclarationDescriptor::NORMAL, resolve, report_error,
|
| + &var_ok);
|
| + if (!var_ok) {
|
| + scope_->RemoveUnresolved(var_proxy);
|
| + } else {
|
| + // At the location of the FunctionDeclaration we assign to the var
|
| + // binding.
|
| + Assignment* assignment = factory()->NewAssignment(
|
| + Token::ASSIGN, var_proxy, NewUnresolved(name, mode), pos);
|
| + return factory()->NewExpressionStatement(assignment,
|
| + RelocInfo::kNoPosition);
|
| + }
|
| + }
|
| return factory()->NewEmptyStatement(RelocInfo::kNoPosition);
|
| }
|
|
|
| @@ -2258,7 +2286,7 @@ Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
|
| proxy, mode, scope_, pos, is_class_declaration,
|
| scope_->class_declaration_group_start());
|
| Variable* outer_class_variable =
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
|
| + Declare(declaration, DeclarationDescriptor::NORMAL, true, true, CHECK_OK);
|
| proxy->var()->set_initializer_position(position());
|
| // This is needed because a class ("class Name { }") creates two bindings (one
|
| // in the outer scope, and one in the class scope). The method is a function
|
| @@ -3347,7 +3375,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| VariableProxy* proxy = NewUnresolved(names->at(i), mode);
|
| Declaration* declaration = factory()->NewVariableDeclaration(
|
| proxy, mode, scope_, RelocInfo::kNoPosition);
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
|
| + Declare(declaration, DeclarationDescriptor::NORMAL, true, true, CHECK_OK);
|
| inner_vars.Add(declaration->proxy()->var(), zone());
|
| VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
|
| Assignment* assignment =
|
| @@ -3636,7 +3664,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
| Declaration* tdz_decl = factory()->NewVariableDeclaration(
|
| tdz_proxy, LET, scope_, RelocInfo::kNoPosition);
|
| Variable* tdz_var = Declare(tdz_decl, DeclarationDescriptor::NORMAL,
|
| - true, CHECK_OK);
|
| + true, true, CHECK_OK);
|
| tdz_var->set_initializer_position(position());
|
| }
|
| }
|
| @@ -4477,7 +4505,7 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
|
| Declaration* declaration = factory()->NewVariableDeclaration(
|
| proxy, CONST, block_scope, pos, is_class_declaration,
|
| scope_->class_declaration_group_start());
|
| - Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
|
| + Declare(declaration, DeclarationDescriptor::NORMAL, true, true, CHECK_OK);
|
| }
|
|
|
| Expression* extends = NULL;
|
|
|