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

Side by Side Diff: src/parser.cc

Issue 943543002: [strong] Declaration-after-use errors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebased (error handling is split off) Created 5 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 unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/scopes.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 return factory->NewNumberLiteral(value, pos); 699 return factory->NewNumberLiteral(value, pos);
700 } 700 }
701 default: 701 default:
702 DCHECK(false); 702 DCHECK(false);
703 } 703 }
704 return NULL; 704 return NULL;
705 } 705 }
706 706
707 707
708 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name, 708 Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
709 int pos, Scope* scope, 709 int start_position,
710 int end_position,
711 Scope* scope,
710 AstNodeFactory* factory) { 712 AstNodeFactory* factory) {
711 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); 713 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
712 714
713 // Arrow function parameters are parsed as an expression. When 715 // Arrow function parameters are parsed as an expression. When
714 // parsing lazily, it is enough to create a VariableProxy in order 716 // parsing lazily, it is enough to create a VariableProxy in order
715 // for Traits::DeclareArrowParametersFromExpression() to be able to 717 // for Traits::DeclareArrowParametersFromExpression() to be able to
716 // pick the names of the parameters. 718 // pick the names of the parameters.
717 return parser_->parsing_lazy_arrow_parameters_ 719 return parser_->parsing_lazy_arrow_parameters_
718 ? factory->NewVariableProxy(name, false, pos) 720 ? factory->NewVariableProxy(name, false, start_position,
719 : scope->NewUnresolved(factory, name, pos); 721 end_position)
722 : scope->NewUnresolved(factory, name, start_position,
723 end_position);
720 } 724 }
721 725
722 726
723 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner, 727 Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
724 AstNodeFactory* factory) { 728 AstNodeFactory* factory) {
725 const AstRawString* symbol = GetSymbol(scanner); 729 const AstRawString* symbol = GetSymbol(scanner);
726 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); 730 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
727 return factory->NewStringLiteral(symbol, pos); 731 return factory->NewStringLiteral(symbol, pos);
728 } 732 }
729 733
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 } 1768 }
1765 1769
1766 1770
1767 VariableProxy* Parser::NewUnresolved(const AstRawString* name, 1771 VariableProxy* Parser::NewUnresolved(const AstRawString* name,
1768 VariableMode mode) { 1772 VariableMode mode) {
1769 // If we are inside a function, a declaration of a var/const variable is a 1773 // If we are inside a function, a declaration of a var/const variable is a
1770 // truly local variable, and the scope of the variable is always the function 1774 // truly local variable, and the scope of the variable is always the function
1771 // scope. 1775 // scope.
1772 // Let/const variables in harmony mode are always added to the immediately 1776 // Let/const variables in harmony mode are always added to the immediately
1773 // enclosing scope. 1777 // enclosing scope.
1774 return DeclarationScope(mode)->NewUnresolved(factory(), name, position()); 1778 return DeclarationScope(mode)->NewUnresolved(factory(), name,
1779 scanner()->location().beg_pos,
1780 scanner()->location().end_pos);
1775 } 1781 }
1776 1782
1777 1783
1778 void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { 1784 Variable* Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
1779 VariableProxy* proxy = declaration->proxy(); 1785 VariableProxy* proxy = declaration->proxy();
1780 DCHECK(proxy->raw_name() != NULL); 1786 DCHECK(proxy->raw_name() != NULL);
1781 const AstRawString* name = proxy->raw_name(); 1787 const AstRawString* name = proxy->raw_name();
1782 VariableMode mode = declaration->mode(); 1788 VariableMode mode = declaration->mode();
1783 Scope* declaration_scope = DeclarationScope(mode); 1789 Scope* declaration_scope = DeclarationScope(mode);
1784 Variable* var = NULL; 1790 Variable* var = NULL;
1785 1791
1786 // If a suitable scope exists, then we can statically declare this 1792 // If a suitable scope exists, then we can statically declare this
1787 // variable and also set its mode. In any case, a Declaration node 1793 // variable and also set its mode. In any case, a Declaration node
1788 // will be added to the scope so that the declaration can be added 1794 // will be added to the scope so that the declaration can be added
1789 // to the corresponding activation frame at runtime if necessary. 1795 // to the corresponding activation frame at runtime if necessary.
1790 // For instance declarations inside an eval scope need to be added 1796 // For instance declarations inside an eval scope need to be added
1791 // to the calling function context. 1797 // to the calling function context.
1792 // Similarly, strict mode eval scope does not leak variable declarations to 1798 // Similarly, strict mode eval scope does not leak variable declarations to
1793 // the caller's scope so we declare all locals, too. 1799 // the caller's scope so we declare all locals, too.
1794 if (declaration_scope->is_function_scope() || 1800 if (declaration_scope->is_function_scope() ||
1795 declaration_scope->is_strict_eval_scope() || 1801 declaration_scope->is_strict_eval_scope() ||
1796 declaration_scope->is_block_scope() || 1802 declaration_scope->is_block_scope() ||
1797 declaration_scope->is_module_scope() || 1803 declaration_scope->is_module_scope() ||
1798 declaration_scope->is_script_scope()) { 1804 declaration_scope->is_script_scope()) {
1799 // Declare the variable in the declaration scope. 1805 // Declare the variable in the declaration scope.
1800 var = declaration_scope->LookupLocal(name); 1806 var = declaration_scope->LookupLocal(name);
1801 if (var == NULL) { 1807 if (var == NULL) {
1802 // Declare the name. 1808 // Declare the name.
1803 var = declaration_scope->DeclareLocal( 1809 var = declaration_scope->DeclareLocal(
1804 name, mode, declaration->initialization(), kNotAssigned); 1810 name, mode, declaration->initialization(),
1805 } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode()) 1811 declaration->IsFunctionDeclaration(), kNotAssigned);
1806 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && 1812 } else if (IsLexicalVariableMode(mode) ||
1807 !declaration_scope->is_script_scope())) { 1813 IsLexicalVariableMode(var->mode()) ||
1814 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1815 !declaration_scope->is_script_scope())) {
1808 // The name was declared in this scope before; check for conflicting 1816 // The name was declared in this scope before; check for conflicting
1809 // re-declarations. We have a conflict if either of the declarations is 1817 // re-declarations. We have a conflict if either of the declarations is
1810 // not a var (in script scope, we also have to ignore legacy const for 1818 // not a var (in script scope, we also have to ignore legacy const for
1811 // compatibility). There is similar code in runtime.cc in the Declare 1819 // compatibility). There is similar code in runtime.cc in the Declare
1812 // functions. The function CheckConflictingVarDeclarations checks for 1820 // functions. The function CheckConflictingVarDeclarations checks for
1813 // var and let bindings from different scopes whereas this is a check for 1821 // var and let bindings from different scopes whereas this is a check for
1814 // conflicting declarations within the same scope. This check also covers 1822 // conflicting declarations within the same scope. This check also covers
1815 // the special case 1823 // the special case
1816 // 1824 //
1817 // function () { let x; { var x; } } 1825 // function () { let x; { var x; } }
1818 // 1826 //
1819 // because the var declaration is hoisted to the function scope where 'x' 1827 // because the var declaration is hoisted to the function scope where 'x'
1820 // is already bound. 1828 // is already bound.
1821 DCHECK(IsDeclaredVariableMode(var->mode())); 1829 DCHECK(IsDeclaredVariableMode(var->mode()));
1822 if (allow_harmony_scoping() && is_strict(language_mode())) { 1830 if (allow_harmony_scoping() && is_strict(language_mode())) {
1823 // In harmony we treat re-declarations as early errors. See 1831 // In harmony we treat re-declarations as early errors. See
1824 // ES5 16 for a definition of early errors. 1832 // ES5 16 for a definition of early errors.
1825 ParserTraits::ReportMessage("var_redeclaration", name); 1833 ParserTraits::ReportMessage("var_redeclaration", name);
1826 *ok = false; 1834 *ok = false;
1827 return; 1835 return nullptr;
1828 } 1836 }
1829 Expression* expression = NewThrowTypeError( 1837 Expression* expression = NewThrowTypeError(
1830 "var_redeclaration", name, declaration->position()); 1838 "var_redeclaration", name, declaration->position());
1831 declaration_scope->SetIllegalRedeclaration(expression); 1839 declaration_scope->SetIllegalRedeclaration(expression);
1832 } else if (mode == VAR) { 1840 } else if (mode == VAR) {
1833 var->set_maybe_assigned(); 1841 var->set_maybe_assigned();
1834 } 1842 }
1835 } 1843 }
1836 1844
1837 // We add a declaration node for every declaration. The compiler 1845 // We add a declaration node for every declaration. The compiler
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 // Note that if 'f' is accessed from inside the 'with' statement, it 1899 // Note that if 'f' is accessed from inside the 'with' statement, it
1892 // will be allocated in the context (because we must be able to look 1900 // will be allocated in the context (because we must be able to look
1893 // it up dynamically) but it will also be accessed statically, i.e., 1901 // it up dynamically) but it will also be accessed statically, i.e.,
1894 // with a context slot index and a context chain length for this 1902 // with a context slot index and a context chain length for this
1895 // initialization code. Thus, inside the 'with' statement, we need 1903 // initialization code. Thus, inside the 'with' statement, we need
1896 // both access to the static and the dynamic context chain; the 1904 // both access to the static and the dynamic context chain; the
1897 // runtime needs to provide both. 1905 // runtime needs to provide both.
1898 if (resolve && var != NULL) { 1906 if (resolve && var != NULL) {
1899 proxy->BindTo(var); 1907 proxy->BindTo(var);
1900 } 1908 }
1909 return var;
1901 } 1910 }
1902 1911
1903 1912
1904 // Language extension which is only enabled for source files loaded 1913 // Language extension which is only enabled for source files loaded
1905 // through the API's extension mechanism. A native function 1914 // through the API's extension mechanism. A native function
1906 // declaration is resolved by looking up the function through a 1915 // declaration is resolved by looking up the function through a
1907 // callback provided by the extension. 1916 // callback provided by the extension.
1908 Statement* Parser::ParseNativeDeclaration(bool* ok) { 1917 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1909 int pos = peek_position(); 1918 int pos = peek_position();
1910 Expect(Token::FUNCTION, CHECK_OK); 1919 Expect(Token::FUNCTION, CHECK_OK);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 const AstRawString* name = 2020 const AstRawString* name =
2012 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 2021 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2013 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), 2022 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2014 is_strict_reserved, pos, CHECK_OK); 2023 is_strict_reserved, pos, CHECK_OK);
2015 2024
2016 VariableMode mode = is_strong(language_mode()) ? CONST : LET; 2025 VariableMode mode = is_strong(language_mode()) ? CONST : LET;
2017 VariableProxy* proxy = NewUnresolved(name, mode); 2026 VariableProxy* proxy = NewUnresolved(name, mode);
2018 Declaration* declaration = 2027 Declaration* declaration =
2019 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); 2028 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2020 Declare(declaration, true, CHECK_OK); 2029 Declare(declaration, true, CHECK_OK);
2021 proxy->var()->set_initializer_position(pos); 2030 proxy->var()->set_initializer_position(position());
2022 2031
2023 Token::Value init_op = 2032 Token::Value init_op =
2024 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; 2033 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET;
2025 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); 2034 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
2026 Statement* assignment_statement = 2035 Statement* assignment_statement =
2027 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 2036 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2028 if (names) names->Add(name, zone()); 2037 if (names) names->Add(name, zone());
2029 return assignment_statement; 2038 return assignment_statement;
2030 } 2039 }
2031 2040
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2220 is_for_iteration_variable = 2229 is_for_iteration_variable =
2221 var_context == kForStatement && 2230 var_context == kForStatement &&
2222 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); 2231 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2223 if (is_for_iteration_variable && mode == CONST) { 2232 if (is_for_iteration_variable && mode == CONST) {
2224 needs_init = false; 2233 needs_init = false;
2225 } 2234 }
2226 2235
2227 VariableProxy* proxy = NewUnresolved(name, mode); 2236 VariableProxy* proxy = NewUnresolved(name, mode);
2228 Declaration* declaration = 2237 Declaration* declaration =
2229 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); 2238 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2230 Declare(declaration, mode != VAR, CHECK_OK); 2239 Variable* var = Declare(declaration, mode != VAR, CHECK_OK);
2240 DCHECK(var != nullptr);
arv (Not doing code reviews) 2015/02/25 16:37:32 DCHECK_NOT_NULL
marja 2015/02/26 12:55:42 Done.
2241 DCHECK(!proxy->is_resolved() || proxy->var() == var);
2231 nvars++; 2242 nvars++;
2232 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 2243 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2233 ReportMessage("too_many_variables"); 2244 ReportMessage("too_many_variables");
2234 *ok = false; 2245 *ok = false;
2235 return NULL; 2246 return NULL;
2236 } 2247 }
2237 if (names) names->Add(name, zone()); 2248 if (names) names->Add(name, zone());
2238 2249
2239 // Parse initialization expression if present and/or needed. A 2250 // Parse initialization expression if present and/or needed. A
2240 // declaration of the form: 2251 // declaration of the form:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2274 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 2285 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2275 // Don't infer if it is "a = function(){...}();"-like expression. 2286 // Don't infer if it is "a = function(){...}();"-like expression.
2276 if (fni_ != NULL && 2287 if (fni_ != NULL &&
2277 value->AsCall() == NULL && 2288 value->AsCall() == NULL &&
2278 value->AsCallNew() == NULL) { 2289 value->AsCallNew() == NULL) {
2279 fni_->Infer(); 2290 fni_->Infer();
2280 } else { 2291 } else {
2281 fni_->RemoveLastFunction(); 2292 fni_->RemoveLastFunction();
2282 } 2293 }
2283 if (decl_props != NULL) *decl_props = kHasInitializers; 2294 if (decl_props != NULL) *decl_props = kHasInitializers;
2284 } 2295 // Record the end position of the initializer.
2285 2296 var->set_initializer_position(scanner()->location().end_pos);
2286 // Record the end position of the initializer. 2297 } else {
2287 if (proxy->is_resolved()) { 2298 // Record the end position of the initializer.
arv (Not doing code reviews) 2015/02/25 16:37:32 Maybe move this comment to before the if since it
marja 2015/02/26 12:55:42 Hmm, that's kinda far away... instead, I made thes
2288 proxy->var()->set_initializer_position(position()); 2299 var->set_initializer_position(position());
2289 } 2300 }
2290 2301
2291 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. 2302 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2292 if (value == NULL && needs_init) { 2303 if (value == NULL && needs_init) {
2293 value = GetLiteralUndefined(position()); 2304 value = GetLiteralUndefined(position());
2294 } 2305 }
2295 2306
2296 // Global variable declarations must be compiled in a specific 2307 // Global variable declarations must be compiled in a specific
2297 // way. When the script containing the global variable declaration 2308 // way. When the script containing the global variable declaration
2298 // is entered, the global variable must be declared, so that if it 2309 // is entered, the global variable must be declared, so that if it
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
2783 if (tok == Token::CATCH) { 2794 if (tok == Token::CATCH) {
2784 Consume(Token::CATCH); 2795 Consume(Token::CATCH);
2785 2796
2786 Expect(Token::LPAREN, CHECK_OK); 2797 Expect(Token::LPAREN, CHECK_OK);
2787 catch_scope = NewScope(scope_, CATCH_SCOPE); 2798 catch_scope = NewScope(scope_, CATCH_SCOPE);
2788 catch_scope->set_start_position(scanner()->location().beg_pos); 2799 catch_scope->set_start_position(scanner()->location().beg_pos);
2789 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 2800 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2790 2801
2791 Expect(Token::RPAREN, CHECK_OK); 2802 Expect(Token::RPAREN, CHECK_OK);
2792 2803
2793 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized); 2804 catch_variable =
2805 catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, false);
2794 BlockState block_state(&scope_, catch_scope); 2806 BlockState block_state(&scope_, catch_scope);
2795 catch_block = ParseBlock(NULL, CHECK_OK); 2807 catch_block = ParseBlock(NULL, CHECK_OK);
2796 2808
2797 catch_scope->set_end_position(scanner()->location().end_pos); 2809 catch_scope->set_end_position(scanner()->location().end_pos);
2798 tok = peek(); 2810 tok = peek();
2799 } 2811 }
2800 2812
2801 Block* finally_block = NULL; 2813 Block* finally_block = NULL;
2802 DCHECK(tok == Token::FINALLY || catch_block != NULL); 2814 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2803 if (tok == Token::FINALLY) { 2815 if (tok == Token::FINALLY) {
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 3087
3076 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, 3088 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false,
3077 RelocInfo::kNoPosition); 3089 RelocInfo::kNoPosition);
3078 int pos = scanner()->location().beg_pos; 3090 int pos = scanner()->location().beg_pos;
3079 ZoneList<Variable*> inner_vars(names->length(), zone()); 3091 ZoneList<Variable*> inner_vars(names->length(), zone());
3080 3092
3081 // For each let variable x: 3093 // For each let variable x:
3082 // make statement: let x = temp_x. 3094 // make statement: let x = temp_x.
3083 for (int i = 0; i < names->length(); i++) { 3095 for (int i = 0; i < names->length(); i++) {
3084 VariableProxy* proxy = NewUnresolved(names->at(i), LET); 3096 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3085 Declaration* declaration = 3097 Declaration* declaration = factory()->NewVariableDeclaration(
3086 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); 3098 proxy, LET, scope_, RelocInfo::kNoPosition);
3087 Declare(declaration, true, CHECK_OK); 3099 Declare(declaration, true, CHECK_OK);
3088 inner_vars.Add(declaration->proxy()->var(), zone()); 3100 inner_vars.Add(declaration->proxy()->var(), zone());
3089 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 3101 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3090 Assignment* assignment = factory()->NewAssignment( 3102 Assignment* assignment = factory()->NewAssignment(
3091 Token::INIT_LET, proxy, temp_proxy, pos); 3103 Token::INIT_LET, proxy, temp_proxy, pos);
3092 Statement* assignment_statement = factory()->NewExpressionStatement( 3104 Statement* assignment_statement =
3093 assignment, pos); 3105 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3094 proxy->var()->set_initializer_position(pos); 3106 proxy->var()->set_initializer_position(init->position());
3095 inner_block->AddStatement(assignment_statement, zone()); 3107 inner_block->AddStatement(assignment_statement, zone());
3096 } 3108 }
3097 3109
3098 // Make statement: if (first == 1) { first = 0; } else { next; } 3110 // Make statement: if (first == 1) { first = 0; } else { next; }
3099 if (next) { 3111 if (next) {
3100 DCHECK(first); 3112 DCHECK(first);
3101 Expression* compare = NULL; 3113 Expression* compare = NULL;
3102 // Make compare expression: first == 1. 3114 // Make compare expression: first == 1.
3103 { 3115 {
3104 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3116 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3232 if (peek() != Token::SEMICOLON) { 3244 if (peek() != Token::SEMICOLON) {
3233 if (peek() == Token::VAR || 3245 if (peek() == Token::VAR ||
3234 (peek() == Token::CONST && is_sloppy(language_mode()))) { 3246 (peek() == Token::CONST && is_sloppy(language_mode()))) {
3235 const AstRawString* name = NULL; 3247 const AstRawString* name = NULL;
3236 VariableDeclarationProperties decl_props = kHasNoInitializers; 3248 VariableDeclarationProperties decl_props = kHasNoInitializers;
3237 Block* variable_statement = 3249 Block* variable_statement =
3238 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 3250 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3239 CHECK_OK); 3251 CHECK_OK);
3240 bool accept_OF = decl_props == kHasNoInitializers; 3252 bool accept_OF = decl_props == kHasNoInitializers;
3241 ForEachStatement::VisitMode mode; 3253 ForEachStatement::VisitMode mode;
3242 int each_pos = position(); 3254 int each_beg_pos = scanner()->location().beg_pos;
3255 int each_end_pos = scanner()->location().end_pos;
3243 3256
3244 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { 3257 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) {
3245 if (!*ok) return nullptr; 3258 if (!*ok) return nullptr;
3246 ForEachStatement* loop = 3259 ForEachStatement* loop =
3247 factory()->NewForEachStatement(mode, labels, stmt_pos); 3260 factory()->NewForEachStatement(mode, labels, stmt_pos);
3248 Target target(&this->target_stack_, loop); 3261 Target target(&this->target_stack_, loop);
3249 3262
3250 Expression* enumerable = ParseExpression(true, CHECK_OK); 3263 Expression* enumerable = ParseExpression(true, CHECK_OK);
3251 Expect(Token::RPAREN, CHECK_OK); 3264 Expect(Token::RPAREN, CHECK_OK);
3252 3265
3253 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); 3266 VariableProxy* each =
3267 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos);
3254 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3268 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3255 InitializeForEachStatement(loop, each, enumerable, body); 3269 InitializeForEachStatement(loop, each, enumerable, body);
3256 Block* result = 3270 Block* result =
3257 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 3271 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3258 result->AddStatement(variable_statement, zone()); 3272 result->AddStatement(variable_statement, zone());
3259 result->AddStatement(loop, zone()); 3273 result->AddStatement(loop, zone());
3260 scope_ = saved_scope; 3274 scope_ = saved_scope;
3261 for_scope->set_end_position(scanner()->location().end_pos); 3275 for_scope->set_end_position(scanner()->location().end_pos);
3262 for_scope = for_scope->FinalizeBlockScope(); 3276 for_scope = for_scope->FinalizeBlockScope();
3263 DCHECK(for_scope == NULL); 3277 DCHECK(for_scope == NULL);
3264 // Parsed for-in loop w/ variable/const declaration. 3278 // Parsed for-in loop w/ variable/const declaration.
3265 return result; 3279 return result;
3266 } else { 3280 } else {
3267 init = variable_statement; 3281 init = variable_statement;
3268 } 3282 }
3269 } else if ((peek() == Token::LET || peek() == Token::CONST) && 3283 } else if ((peek() == Token::LET || peek() == Token::CONST) &&
3270 is_strict(language_mode())) { 3284 is_strict(language_mode())) {
3271 bool is_const = peek() == Token::CONST; 3285 bool is_const = peek() == Token::CONST;
3272 const AstRawString* name = NULL; 3286 const AstRawString* name = NULL;
3273 VariableDeclarationProperties decl_props = kHasNoInitializers; 3287 VariableDeclarationProperties decl_props = kHasNoInitializers;
3274 Block* variable_statement = 3288 Block* variable_statement =
3275 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, 3289 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3276 &name, CHECK_OK); 3290 &name, CHECK_OK);
3277 bool accept_IN = name != NULL && decl_props != kHasInitializers; 3291 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3278 bool accept_OF = decl_props == kHasNoInitializers; 3292 bool accept_OF = decl_props == kHasNoInitializers;
3279 ForEachStatement::VisitMode mode; 3293 ForEachStatement::VisitMode mode;
3280 int each_pos = position(); 3294 int each_beg_pos = scanner()->location().beg_pos;
3295 int each_end_pos = scanner()->location().end_pos;
3281 3296
3282 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { 3297 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) {
3283 if (!*ok) return nullptr; 3298 if (!*ok) return nullptr;
3284 3299
3285 // Rewrite a for-in statement of the form 3300 // Rewrite a for-in statement of the form
3286 // 3301 //
3287 // for (let/const x in e) b 3302 // for (let/const x in e) b
3288 // 3303 //
3289 // into 3304 // into
3290 // 3305 //
3291 // <let x' be a temporary variable> 3306 // <let x' be a temporary variable>
3292 // for (x' in e) { 3307 // for (x' in e) {
3293 // let/const x; 3308 // let/const x;
3294 // x = x'; 3309 // x = x';
3295 // b; 3310 // b;
3296 // } 3311 // }
3297 3312
3298 // TODO(keuchel): Move the temporary variable to the block scope, after 3313 // TODO(keuchel): Move the temporary variable to the block scope, after
3299 // implementing stack allocated block scoped variables. 3314 // implementing stack allocated block scoped variables.
3300 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3315 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3301 ast_value_factory()->dot_for_string()); 3316 ast_value_factory()->dot_for_string());
3302 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos); 3317 VariableProxy* temp_proxy =
3318 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3303 ForEachStatement* loop = 3319 ForEachStatement* loop =
3304 factory()->NewForEachStatement(mode, labels, stmt_pos); 3320 factory()->NewForEachStatement(mode, labels, stmt_pos);
3305 Target target(&this->target_stack_, loop); 3321 Target target(&this->target_stack_, loop);
3306 3322
3307 // The expression does not see the loop variable. 3323 // The expression does not see the loop variable.
3308 scope_ = saved_scope; 3324 scope_ = saved_scope;
3309 Expression* enumerable = ParseExpression(true, CHECK_OK); 3325 Expression* enumerable = ParseExpression(true, CHECK_OK);
3310 scope_ = for_scope; 3326 scope_ = for_scope;
3311 Expect(Token::RPAREN, CHECK_OK); 3327 Expect(Token::RPAREN, CHECK_OK);
3312 3328
3313 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); 3329 VariableProxy* each =
3330 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos);
3314 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3331 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3315 Block* body_block = 3332 Block* body_block =
3316 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3333 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3317 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; 3334 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
3318 Assignment* assignment = factory()->NewAssignment( 3335 Assignment* assignment = factory()->NewAssignment(
3319 init_op, each, temp_proxy, RelocInfo::kNoPosition); 3336 init_op, each, temp_proxy, RelocInfo::kNoPosition);
3320 Statement* assignment_statement = factory()->NewExpressionStatement( 3337 Statement* assignment_statement = factory()->NewExpressionStatement(
3321 assignment, RelocInfo::kNoPosition); 3338 assignment, RelocInfo::kNoPosition);
3322 body_block->AddStatement(variable_statement, zone()); 3339 body_block->AddStatement(variable_statement, zone());
3323 body_block->AddStatement(assignment_statement, zone()); 3340 body_block->AddStatement(assignment_statement, zone());
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
4087 block_scope->set_start_position(scanner()->location().end_pos); 4104 block_scope->set_start_position(scanner()->location().end_pos);
4088 } 4105 }
4089 4106
4090 4107
4091 ClassLiteralChecker checker(this); 4108 ClassLiteralChecker checker(this);
4092 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); 4109 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4093 FunctionLiteral* constructor = NULL; 4110 FunctionLiteral* constructor = NULL;
4094 bool has_seen_constructor = false; 4111 bool has_seen_constructor = false;
4095 4112
4096 Expect(Token::LBRACE, CHECK_OK); 4113 Expect(Token::LBRACE, CHECK_OK);
4114 int body_beg_pos = scanner()->location().beg_pos;
4115
4097 const bool has_extends = extends != nullptr; 4116 const bool has_extends = extends != nullptr;
4098 while (peek() != Token::RBRACE) { 4117 while (peek() != Token::RBRACE) {
4099 if (Check(Token::SEMICOLON)) continue; 4118 if (Check(Token::SEMICOLON)) continue;
4100 if (fni_ != NULL) fni_->Enter(); 4119 if (fni_ != NULL) fni_->Enter();
4101 const bool in_class = true; 4120 const bool in_class = true;
4102 const bool is_static = false; 4121 const bool is_static = false;
4103 bool is_computed_name = false; // Classes do not care about computed 4122 bool is_computed_name = false; // Classes do not care about computed
4104 // property names here. 4123 // property names here.
4105 ObjectLiteral::Property* property = ParsePropertyDefinition( 4124 ObjectLiteral::Property* property = ParsePropertyDefinition(
4106 &checker, in_class, has_extends, is_static, &is_computed_name, 4125 &checker, in_class, has_extends, is_static, &is_computed_name,
(...skipping 19 matching lines...) Expand all
4126 constructor = 4145 constructor =
4127 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); 4146 DefaultConstructor(extends != NULL, block_scope, pos, end_pos);
4128 } 4147 }
4129 4148
4130 block_scope->set_end_position(end_pos); 4149 block_scope->set_end_position(end_pos);
4131 block_scope = block_scope->FinalizeBlockScope(); 4150 block_scope = block_scope->FinalizeBlockScope();
4132 4151
4133 if (name != NULL) { 4152 if (name != NULL) {
4134 DCHECK_NOT_NULL(proxy); 4153 DCHECK_NOT_NULL(proxy);
4135 DCHECK_NOT_NULL(block_scope); 4154 DCHECK_NOT_NULL(block_scope);
4136 proxy->var()->set_initializer_position(end_pos); 4155 proxy->var()->set_initializer_position(body_beg_pos);
4137 } 4156 }
4138 4157
4139 return factory()->NewClassLiteral(name, block_scope, proxy, extends, 4158 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4140 constructor, properties, pos, end_pos); 4159 constructor, properties, pos, end_pos);
4141 } 4160 }
4142 4161
4143 4162
4144 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4163 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4145 // CallRuntime :: 4164 // CallRuntime ::
4146 // '%' Identifier Arguments 4165 // '%' Identifier Arguments
(...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after
5414 } else { 5433 } else {
5415 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 5434 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5416 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 5435 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5417 raw_string->length()); 5436 raw_string->length());
5418 } 5437 }
5419 } 5438 }
5420 5439
5421 return running_hash; 5440 return running_hash;
5422 } 5441 }
5423 } } // namespace v8::internal 5442 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/scopes.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698