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

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: computed prop names comment fix Created 5 years, 10 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') | no next file with comments »
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() ? Variable::FUNCTION
1806 || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) && 1812 : Variable::NORMAL,
1807 !declaration_scope->is_script_scope())) { 1813 kNotAssigned);
1814 } else if (IsLexicalVariableMode(mode) ||
1815 IsLexicalVariableMode(var->mode()) ||
1816 ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
1817 !declaration_scope->is_script_scope())) {
1808 // The name was declared in this scope before; check for conflicting 1818 // The name was declared in this scope before; check for conflicting
1809 // re-declarations. We have a conflict if either of the declarations is 1819 // 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 1820 // 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 1821 // compatibility). There is similar code in runtime.cc in the Declare
1812 // functions. The function CheckConflictingVarDeclarations checks for 1822 // functions. The function CheckConflictingVarDeclarations checks for
1813 // var and let bindings from different scopes whereas this is a check for 1823 // var and let bindings from different scopes whereas this is a check for
1814 // conflicting declarations within the same scope. This check also covers 1824 // conflicting declarations within the same scope. This check also covers
1815 // the special case 1825 // the special case
1816 // 1826 //
1817 // function () { let x; { var x; } } 1827 // function () { let x; { var x; } }
1818 // 1828 //
1819 // because the var declaration is hoisted to the function scope where 'x' 1829 // because the var declaration is hoisted to the function scope where 'x'
1820 // is already bound. 1830 // is already bound.
1821 DCHECK(IsDeclaredVariableMode(var->mode())); 1831 DCHECK(IsDeclaredVariableMode(var->mode()));
1822 if (allow_harmony_scoping() && is_strict(language_mode())) { 1832 if (allow_harmony_scoping() && is_strict(language_mode())) {
1823 // In harmony we treat re-declarations as early errors. See 1833 // In harmony we treat re-declarations as early errors. See
1824 // ES5 16 for a definition of early errors. 1834 // ES5 16 for a definition of early errors.
1825 ParserTraits::ReportMessage("var_redeclaration", name); 1835 ParserTraits::ReportMessage("var_redeclaration", name);
1826 *ok = false; 1836 *ok = false;
1827 return; 1837 return nullptr;
1828 } 1838 }
1829 Expression* expression = NewThrowTypeError( 1839 Expression* expression = NewThrowTypeError(
1830 "var_redeclaration", name, declaration->position()); 1840 "var_redeclaration", name, declaration->position());
1831 declaration_scope->SetIllegalRedeclaration(expression); 1841 declaration_scope->SetIllegalRedeclaration(expression);
1832 } else if (mode == VAR) { 1842 } else if (mode == VAR) {
1833 var->set_maybe_assigned(); 1843 var->set_maybe_assigned();
1834 } 1844 }
1835 } 1845 }
1836 1846
1837 // We add a declaration node for every declaration. The compiler 1847 // 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 1901 // 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 1902 // 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., 1903 // 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 1904 // with a context slot index and a context chain length for this
1895 // initialization code. Thus, inside the 'with' statement, we need 1905 // initialization code. Thus, inside the 'with' statement, we need
1896 // both access to the static and the dynamic context chain; the 1906 // both access to the static and the dynamic context chain; the
1897 // runtime needs to provide both. 1907 // runtime needs to provide both.
1898 if (resolve && var != NULL) { 1908 if (resolve && var != NULL) {
1899 proxy->BindTo(var); 1909 proxy->BindTo(var);
1900 } 1910 }
1911 return var;
1901 } 1912 }
1902 1913
1903 1914
1904 // Language extension which is only enabled for source files loaded 1915 // Language extension which is only enabled for source files loaded
1905 // through the API's extension mechanism. A native function 1916 // through the API's extension mechanism. A native function
1906 // declaration is resolved by looking up the function through a 1917 // declaration is resolved by looking up the function through a
1907 // callback provided by the extension. 1918 // callback provided by the extension.
1908 Statement* Parser::ParseNativeDeclaration(bool* ok) { 1919 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1909 int pos = peek_position(); 1920 int pos = peek_position();
1910 Expect(Token::FUNCTION, CHECK_OK); 1921 Expect(Token::FUNCTION, CHECK_OK);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 const AstRawString* name = 2022 const AstRawString* name =
2012 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 2023 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2013 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), 2024 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2014 is_strict_reserved, pos, CHECK_OK); 2025 is_strict_reserved, pos, CHECK_OK);
2015 2026
2016 VariableMode mode = is_strong(language_mode()) ? CONST : LET; 2027 VariableMode mode = is_strong(language_mode()) ? CONST : LET;
2017 VariableProxy* proxy = NewUnresolved(name, mode); 2028 VariableProxy* proxy = NewUnresolved(name, mode);
2018 Declaration* declaration = 2029 Declaration* declaration =
2019 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); 2030 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2020 Declare(declaration, true, CHECK_OK); 2031 Declare(declaration, true, CHECK_OK);
2021 proxy->var()->set_initializer_position(pos); 2032 proxy->var()->set_initializer_position(position());
2022 2033
2023 Token::Value init_op = 2034 Token::Value init_op =
2024 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET; 2035 is_strong(language_mode()) ? Token::INIT_CONST : Token::INIT_LET;
2025 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos); 2036 Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
2026 Statement* assignment_statement = 2037 Statement* assignment_statement =
2027 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition); 2038 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
2028 if (names) names->Add(name, zone()); 2039 if (names) names->Add(name, zone());
2029 return assignment_statement; 2040 return assignment_statement;
2030 } 2041 }
2031 2042
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2220 is_for_iteration_variable = 2231 is_for_iteration_variable =
2221 var_context == kForStatement && 2232 var_context == kForStatement &&
2222 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of"))); 2233 (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
2223 if (is_for_iteration_variable && mode == CONST) { 2234 if (is_for_iteration_variable && mode == CONST) {
2224 needs_init = false; 2235 needs_init = false;
2225 } 2236 }
2226 2237
2227 VariableProxy* proxy = NewUnresolved(name, mode); 2238 VariableProxy* proxy = NewUnresolved(name, mode);
2228 Declaration* declaration = 2239 Declaration* declaration =
2229 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); 2240 factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
2230 Declare(declaration, mode != VAR, CHECK_OK); 2241 Variable* var = Declare(declaration, mode != VAR, CHECK_OK);
2242 DCHECK_NOT_NULL(var);
2243 DCHECK(!proxy->is_resolved() || proxy->var() == var);
2231 nvars++; 2244 nvars++;
2232 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { 2245 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
2233 ReportMessage("too_many_variables"); 2246 ReportMessage("too_many_variables");
2234 *ok = false; 2247 *ok = false;
2235 return NULL; 2248 return NULL;
2236 } 2249 }
2237 if (names) names->Add(name, zone()); 2250 if (names) names->Add(name, zone());
2238 2251
2239 // Parse initialization expression if present and/or needed. A 2252 // Parse initialization expression if present and/or needed. A
2240 // declaration of the form: 2253 // declaration of the form:
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2274 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 2287 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2275 // Don't infer if it is "a = function(){...}();"-like expression. 2288 // Don't infer if it is "a = function(){...}();"-like expression.
2276 if (fni_ != NULL && 2289 if (fni_ != NULL &&
2277 value->AsCall() == NULL && 2290 value->AsCall() == NULL &&
2278 value->AsCallNew() == NULL) { 2291 value->AsCallNew() == NULL) {
2279 fni_->Infer(); 2292 fni_->Infer();
2280 } else { 2293 } else {
2281 fni_->RemoveLastFunction(); 2294 fni_->RemoveLastFunction();
2282 } 2295 }
2283 if (decl_props != NULL) *decl_props = kHasInitializers; 2296 if (decl_props != NULL) *decl_props = kHasInitializers;
2284 } 2297 // End position of the initializer is after the assignment expression.
2285 2298 var->set_initializer_position(scanner()->location().end_pos);
2286 // Record the end position of the initializer. 2299 } else {
2287 if (proxy->is_resolved()) { 2300 // End position of the initializer is after the variable.
2288 proxy->var()->set_initializer_position(position()); 2301 var->set_initializer_position(position());
2289 } 2302 }
2290 2303
2291 // Make sure that 'const x' and 'let x' initialize 'x' to undefined. 2304 // Make sure that 'const x' and 'let x' initialize 'x' to undefined.
2292 if (value == NULL && needs_init) { 2305 if (value == NULL && needs_init) {
2293 value = GetLiteralUndefined(position()); 2306 value = GetLiteralUndefined(position());
2294 } 2307 }
2295 2308
2296 // Global variable declarations must be compiled in a specific 2309 // Global variable declarations must be compiled in a specific
2297 // way. When the script containing the global variable declaration 2310 // way. When the script containing the global variable declaration
2298 // is entered, the global variable must be declared, so that if it 2311 // 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) { 2796 if (tok == Token::CATCH) {
2784 Consume(Token::CATCH); 2797 Consume(Token::CATCH);
2785 2798
2786 Expect(Token::LPAREN, CHECK_OK); 2799 Expect(Token::LPAREN, CHECK_OK);
2787 catch_scope = NewScope(scope_, CATCH_SCOPE); 2800 catch_scope = NewScope(scope_, CATCH_SCOPE);
2788 catch_scope->set_start_position(scanner()->location().beg_pos); 2801 catch_scope->set_start_position(scanner()->location().beg_pos);
2789 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 2802 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
2790 2803
2791 Expect(Token::RPAREN, CHECK_OK); 2804 Expect(Token::RPAREN, CHECK_OK);
2792 2805
2793 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized); 2806 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
2807 Variable::NORMAL);
2794 BlockState block_state(&scope_, catch_scope); 2808 BlockState block_state(&scope_, catch_scope);
2795 catch_block = ParseBlock(NULL, CHECK_OK); 2809 catch_block = ParseBlock(NULL, CHECK_OK);
2796 2810
2797 catch_scope->set_end_position(scanner()->location().end_pos); 2811 catch_scope->set_end_position(scanner()->location().end_pos);
2798 tok = peek(); 2812 tok = peek();
2799 } 2813 }
2800 2814
2801 Block* finally_block = NULL; 2815 Block* finally_block = NULL;
2802 DCHECK(tok == Token::FINALLY || catch_block != NULL); 2816 DCHECK(tok == Token::FINALLY || catch_block != NULL);
2803 if (tok == Token::FINALLY) { 2817 if (tok == Token::FINALLY) {
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 3089
3076 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false, 3090 Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false,
3077 RelocInfo::kNoPosition); 3091 RelocInfo::kNoPosition);
3078 int pos = scanner()->location().beg_pos; 3092 int pos = scanner()->location().beg_pos;
3079 ZoneList<Variable*> inner_vars(names->length(), zone()); 3093 ZoneList<Variable*> inner_vars(names->length(), zone());
3080 3094
3081 // For each let variable x: 3095 // For each let variable x:
3082 // make statement: let x = temp_x. 3096 // make statement: let x = temp_x.
3083 for (int i = 0; i < names->length(); i++) { 3097 for (int i = 0; i < names->length(); i++) {
3084 VariableProxy* proxy = NewUnresolved(names->at(i), LET); 3098 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3085 Declaration* declaration = 3099 Declaration* declaration = factory()->NewVariableDeclaration(
3086 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); 3100 proxy, LET, scope_, RelocInfo::kNoPosition);
3087 Declare(declaration, true, CHECK_OK); 3101 Declare(declaration, true, CHECK_OK);
3088 inner_vars.Add(declaration->proxy()->var(), zone()); 3102 inner_vars.Add(declaration->proxy()->var(), zone());
3089 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i)); 3103 VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
3090 Assignment* assignment = factory()->NewAssignment( 3104 Assignment* assignment = factory()->NewAssignment(
3091 Token::INIT_LET, proxy, temp_proxy, pos); 3105 Token::INIT_LET, proxy, temp_proxy, pos);
3092 Statement* assignment_statement = factory()->NewExpressionStatement( 3106 Statement* assignment_statement =
3093 assignment, pos); 3107 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3094 proxy->var()->set_initializer_position(pos); 3108 proxy->var()->set_initializer_position(init->position());
3095 inner_block->AddStatement(assignment_statement, zone()); 3109 inner_block->AddStatement(assignment_statement, zone());
3096 } 3110 }
3097 3111
3098 // Make statement: if (first == 1) { first = 0; } else { next; } 3112 // Make statement: if (first == 1) { first = 0; } else { next; }
3099 if (next) { 3113 if (next) {
3100 DCHECK(first); 3114 DCHECK(first);
3101 Expression* compare = NULL; 3115 Expression* compare = NULL;
3102 // Make compare expression: first == 1. 3116 // Make compare expression: first == 1.
3103 { 3117 {
3104 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3118 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3232 if (peek() != Token::SEMICOLON) { 3246 if (peek() != Token::SEMICOLON) {
3233 if (peek() == Token::VAR || 3247 if (peek() == Token::VAR ||
3234 (peek() == Token::CONST && is_sloppy(language_mode()))) { 3248 (peek() == Token::CONST && is_sloppy(language_mode()))) {
3235 const AstRawString* name = NULL; 3249 const AstRawString* name = NULL;
3236 VariableDeclarationProperties decl_props = kHasNoInitializers; 3250 VariableDeclarationProperties decl_props = kHasNoInitializers;
3237 Block* variable_statement = 3251 Block* variable_statement =
3238 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 3252 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
3239 CHECK_OK); 3253 CHECK_OK);
3240 bool accept_OF = decl_props == kHasNoInitializers; 3254 bool accept_OF = decl_props == kHasNoInitializers;
3241 ForEachStatement::VisitMode mode; 3255 ForEachStatement::VisitMode mode;
3242 int each_pos = position(); 3256 int each_beg_pos = scanner()->location().beg_pos;
3257 int each_end_pos = scanner()->location().end_pos;
3243 3258
3244 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) { 3259 if (name != NULL && CheckInOrOf(accept_OF, &mode, ok)) {
3245 if (!*ok) return nullptr; 3260 if (!*ok) return nullptr;
3246 ForEachStatement* loop = 3261 ForEachStatement* loop =
3247 factory()->NewForEachStatement(mode, labels, stmt_pos); 3262 factory()->NewForEachStatement(mode, labels, stmt_pos);
3248 Target target(&this->target_stack_, loop); 3263 Target target(&this->target_stack_, loop);
3249 3264
3250 Expression* enumerable = ParseExpression(true, CHECK_OK); 3265 Expression* enumerable = ParseExpression(true, CHECK_OK);
3251 Expect(Token::RPAREN, CHECK_OK); 3266 Expect(Token::RPAREN, CHECK_OK);
3252 3267
3253 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); 3268 VariableProxy* each =
3269 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos);
3254 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3270 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3255 InitializeForEachStatement(loop, each, enumerable, body); 3271 InitializeForEachStatement(loop, each, enumerable, body);
3256 Block* result = 3272 Block* result =
3257 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); 3273 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition);
3258 result->AddStatement(variable_statement, zone()); 3274 result->AddStatement(variable_statement, zone());
3259 result->AddStatement(loop, zone()); 3275 result->AddStatement(loop, zone());
3260 scope_ = saved_scope; 3276 scope_ = saved_scope;
3261 for_scope->set_end_position(scanner()->location().end_pos); 3277 for_scope->set_end_position(scanner()->location().end_pos);
3262 for_scope = for_scope->FinalizeBlockScope(); 3278 for_scope = for_scope->FinalizeBlockScope();
3263 DCHECK(for_scope == NULL); 3279 DCHECK(for_scope == NULL);
3264 // Parsed for-in loop w/ variable/const declaration. 3280 // Parsed for-in loop w/ variable/const declaration.
3265 return result; 3281 return result;
3266 } else { 3282 } else {
3267 init = variable_statement; 3283 init = variable_statement;
3268 } 3284 }
3269 } else if ((peek() == Token::LET || peek() == Token::CONST) && 3285 } else if ((peek() == Token::LET || peek() == Token::CONST) &&
3270 is_strict(language_mode())) { 3286 is_strict(language_mode())) {
3271 bool is_const = peek() == Token::CONST; 3287 bool is_const = peek() == Token::CONST;
3272 const AstRawString* name = NULL; 3288 const AstRawString* name = NULL;
3273 VariableDeclarationProperties decl_props = kHasNoInitializers; 3289 VariableDeclarationProperties decl_props = kHasNoInitializers;
3274 Block* variable_statement = 3290 Block* variable_statement =
3275 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, 3291 ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings,
3276 &name, CHECK_OK); 3292 &name, CHECK_OK);
3277 bool accept_IN = name != NULL && decl_props != kHasInitializers; 3293 bool accept_IN = name != NULL && decl_props != kHasInitializers;
3278 bool accept_OF = decl_props == kHasNoInitializers; 3294 bool accept_OF = decl_props == kHasNoInitializers;
3279 ForEachStatement::VisitMode mode; 3295 ForEachStatement::VisitMode mode;
3280 int each_pos = position(); 3296 int each_beg_pos = scanner()->location().beg_pos;
3297 int each_end_pos = scanner()->location().end_pos;
3281 3298
3282 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) { 3299 if (accept_IN && CheckInOrOf(accept_OF, &mode, ok)) {
3283 if (!*ok) return nullptr; 3300 if (!*ok) return nullptr;
3284 3301
3285 // Rewrite a for-in statement of the form 3302 // Rewrite a for-in statement of the form
3286 // 3303 //
3287 // for (let/const x in e) b 3304 // for (let/const x in e) b
3288 // 3305 //
3289 // into 3306 // into
3290 // 3307 //
3291 // <let x' be a temporary variable> 3308 // <let x' be a temporary variable>
3292 // for (x' in e) { 3309 // for (x' in e) {
3293 // let/const x; 3310 // let/const x;
3294 // x = x'; 3311 // x = x';
3295 // b; 3312 // b;
3296 // } 3313 // }
3297 3314
3298 // TODO(keuchel): Move the temporary variable to the block scope, after 3315 // TODO(keuchel): Move the temporary variable to the block scope, after
3299 // implementing stack allocated block scoped variables. 3316 // implementing stack allocated block scoped variables.
3300 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3317 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3301 ast_value_factory()->dot_for_string()); 3318 ast_value_factory()->dot_for_string());
3302 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos); 3319 VariableProxy* temp_proxy =
3320 factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
3303 ForEachStatement* loop = 3321 ForEachStatement* loop =
3304 factory()->NewForEachStatement(mode, labels, stmt_pos); 3322 factory()->NewForEachStatement(mode, labels, stmt_pos);
3305 Target target(&this->target_stack_, loop); 3323 Target target(&this->target_stack_, loop);
3306 3324
3307 // The expression does not see the loop variable. 3325 // The expression does not see the loop variable.
3308 scope_ = saved_scope; 3326 scope_ = saved_scope;
3309 Expression* enumerable = ParseExpression(true, CHECK_OK); 3327 Expression* enumerable = ParseExpression(true, CHECK_OK);
3310 scope_ = for_scope; 3328 scope_ = for_scope;
3311 Expect(Token::RPAREN, CHECK_OK); 3329 Expect(Token::RPAREN, CHECK_OK);
3312 3330
3313 VariableProxy* each = scope_->NewUnresolved(factory(), name, each_pos); 3331 VariableProxy* each =
3332 scope_->NewUnresolved(factory(), name, each_beg_pos, each_end_pos);
3314 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3333 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3315 Block* body_block = 3334 Block* body_block =
3316 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); 3335 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
3317 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN; 3336 Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
3318 Assignment* assignment = factory()->NewAssignment( 3337 Assignment* assignment = factory()->NewAssignment(
3319 init_op, each, temp_proxy, RelocInfo::kNoPosition); 3338 init_op, each, temp_proxy, RelocInfo::kNoPosition);
3320 Statement* assignment_statement = factory()->NewExpressionStatement( 3339 Statement* assignment_statement = factory()->NewExpressionStatement(
3321 assignment, RelocInfo::kNoPosition); 3340 assignment, RelocInfo::kNoPosition);
3322 body_block->AddStatement(variable_statement, zone()); 3341 body_block->AddStatement(variable_statement, zone());
3323 body_block->AddStatement(assignment_statement, zone()); 3342 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); 4106 block_scope->set_start_position(scanner()->location().end_pos);
4088 } 4107 }
4089 4108
4090 4109
4091 ClassLiteralChecker checker(this); 4110 ClassLiteralChecker checker(this);
4092 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone()); 4111 ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
4093 FunctionLiteral* constructor = NULL; 4112 FunctionLiteral* constructor = NULL;
4094 bool has_seen_constructor = false; 4113 bool has_seen_constructor = false;
4095 4114
4096 Expect(Token::LBRACE, CHECK_OK); 4115 Expect(Token::LBRACE, CHECK_OK);
4116 int body_beg_pos = scanner()->location().beg_pos;
4117
4097 const bool has_extends = extends != nullptr; 4118 const bool has_extends = extends != nullptr;
4098 while (peek() != Token::RBRACE) { 4119 while (peek() != Token::RBRACE) {
4099 if (Check(Token::SEMICOLON)) continue; 4120 if (Check(Token::SEMICOLON)) continue;
4100 if (fni_ != NULL) fni_->Enter(); 4121 if (fni_ != NULL) fni_->Enter();
4101 const bool in_class = true; 4122 const bool in_class = true;
4102 const bool is_static = false; 4123 const bool is_static = false;
4103 bool is_computed_name = false; // Classes do not care about computed 4124 bool is_computed_name = false; // Classes do not care about computed
4104 // property names here. 4125 // property names here.
4105 ObjectLiteral::Property* property = ParsePropertyDefinition( 4126 ObjectLiteral::Property* property = ParsePropertyDefinition(
4106 &checker, in_class, has_extends, is_static, &is_computed_name, 4127 &checker, in_class, has_extends, is_static, &is_computed_name,
(...skipping 19 matching lines...) Expand all
4126 constructor = 4147 constructor =
4127 DefaultConstructor(extends != NULL, block_scope, pos, end_pos); 4148 DefaultConstructor(extends != NULL, block_scope, pos, end_pos);
4128 } 4149 }
4129 4150
4130 block_scope->set_end_position(end_pos); 4151 block_scope->set_end_position(end_pos);
4131 block_scope = block_scope->FinalizeBlockScope(); 4152 block_scope = block_scope->FinalizeBlockScope();
4132 4153
4133 if (name != NULL) { 4154 if (name != NULL) {
4134 DCHECK_NOT_NULL(proxy); 4155 DCHECK_NOT_NULL(proxy);
4135 DCHECK_NOT_NULL(block_scope); 4156 DCHECK_NOT_NULL(block_scope);
4136 proxy->var()->set_initializer_position(end_pos); 4157 proxy->var()->set_initializer_position(body_beg_pos);
4137 } 4158 }
4138 4159
4139 return factory()->NewClassLiteral(name, block_scope, proxy, extends, 4160 return factory()->NewClassLiteral(name, block_scope, proxy, extends,
4140 constructor, properties, pos, end_pos); 4161 constructor, properties, pos, end_pos);
4141 } 4162 }
4142 4163
4143 4164
4144 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4165 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4145 // CallRuntime :: 4166 // CallRuntime ::
4146 // '%' Identifier Arguments 4167 // '%' Identifier Arguments
(...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after
5414 } else { 5435 } else {
5415 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 5436 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5416 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 5437 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5417 raw_string->length()); 5438 raw_string->length());
5418 } 5439 }
5419 } 5440 }
5420 5441
5421 return running_hash; 5442 return running_hash;
5422 } 5443 }
5423 } } // namespace v8::internal 5444 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698