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

Side by Side Diff: src/preparser.cc

Issue 869293002: Lexical declarations should not be allowed in Statement (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove unused error messages 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.cc ('k') | test/cctest/test-parsing.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 <cmath> 5 #include <cmath>
6 6
7 #include "src/allocation.h" 7 #include "src/allocation.h"
8 #include "src/base/logging.h" 8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h" 9 #include "src/conversions-inl.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 155
156 156
157 #define CHECK_OK ok); \ 157 #define CHECK_OK ok); \
158 if (!*ok) return kUnknownSourceElements; \ 158 if (!*ok) return kUnknownSourceElements; \
159 ((void)0 159 ((void)0
160 #define DUMMY ) // to make indentation work 160 #define DUMMY ) // to make indentation work
161 #undef DUMMY 161 #undef DUMMY
162 162
163 163
164 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { 164 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
165 // (Ecma 262 5th Edition, clause 14): 165 // ECMA 262 6th Edition
166 // SourceElement: 166 // StatementListItem[Yield, Return] :
167 // Statement 167 // Statement[?Yield, ?Return]
168 // FunctionDeclaration 168 // Declaration[?Yield]
169 // 169 //
170 // In harmony mode we allow additionally the following productions 170 // Declaration[Yield] :
171 // SourceElement: 171 // HoistableDeclaration[?Yield]
172 // LetDeclaration 172 // ClassDeclaration[?Yield]
173 // ConstDeclaration 173 // LexicalDeclaration[In, ?Yield]
174 // GeneratorDeclaration 174 //
175 // HoistableDeclaration[Yield, Default] :
176 // FunctionDeclaration[?Yield, ?Default]
177 // GeneratorDeclaration[?Yield, ?Default]
178 //
179 // LexicalDeclaration[In, Yield] :
180 // LetOrConst BindingList[?In, ?Yield] ;
175 181
176 switch (peek()) { 182 switch (peek()) {
177 case Token::FUNCTION: 183 case Token::FUNCTION:
178 return ParseFunctionDeclaration(ok); 184 return ParseFunctionDeclaration(ok);
179 case Token::CLASS: 185 case Token::CLASS:
180 return ParseClassDeclaration(ok); 186 return ParseClassDeclaration(ok);
181 case Token::CONST: 187 case Token::CONST:
182 return ParseVariableStatement(kSourceElement, ok); 188 return ParseVariableStatement(kSourceElement, ok);
183 case Token::LET: 189 case Token::LET:
184 DCHECK(allow_harmony_scoping()); 190 DCHECK(allow_harmony_scoping());
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 PreParserTraits::ReportMessageAt(start_location.beg_pos, 304 PreParserTraits::ReportMessageAt(start_location.beg_pos,
299 end_location.end_pos, 305 end_location.end_pos,
300 "strict_function"); 306 "strict_function");
301 *ok = false; 307 *ok = false;
302 return Statement::Default(); 308 return Statement::Default();
303 } else { 309 } else {
304 return statement; 310 return statement;
305 } 311 }
306 } 312 }
307 313
308 case Token::CLASS:
309 return ParseClassDeclaration(CHECK_OK);
310
311 case Token::DEBUGGER: 314 case Token::DEBUGGER:
312 return ParseDebuggerStatement(ok); 315 return ParseDebuggerStatement(ok);
313 316
314 case Token::VAR: 317 case Token::VAR:
315 case Token::CONST:
316 return ParseVariableStatement(kStatement, ok); 318 return ParseVariableStatement(kStatement, ok);
317 319
318 case Token::LET: 320 case Token::CONST:
319 DCHECK(allow_harmony_scoping()); 321 // In ES6 CONST is not allowed as a Statement, only as a
320 if (strict_mode() == STRICT) { 322 // LexicalDeclaration, however we continue to allow it in sloppy mode for
323 // backwards compatibility.
324 if (strict_mode() == SLOPPY) {
321 return ParseVariableStatement(kStatement, ok); 325 return ParseVariableStatement(kStatement, ok);
322 } 326 }
323 // Fall through. 327
328 // Fall through.
324 default: 329 default:
325 return ParseExpressionOrLabelledStatement(ok); 330 return ParseExpressionOrLabelledStatement(ok);
326 } 331 }
327 } 332 }
328 333
329 334
330 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 335 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
331 // FunctionDeclaration :: 336 // FunctionDeclaration ::
332 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 337 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
333 // GeneratorDeclaration :: 338 // GeneratorDeclaration ::
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 439 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
435 // 440 //
436 // * It is a Syntax Error if the code that matches this production is not 441 // * It is a Syntax Error if the code that matches this production is not
437 // contained in extended code. 442 // contained in extended code.
438 // 443 //
439 // However disallowing const in sloppy mode will break compatibility with 444 // However disallowing const in sloppy mode will break compatibility with
440 // existing pages. Therefore we keep allowing const with the old 445 // existing pages. Therefore we keep allowing const with the old
441 // non-harmony semantics in sloppy mode. 446 // non-harmony semantics in sloppy mode.
442 Consume(Token::CONST); 447 Consume(Token::CONST);
443 if (strict_mode() == STRICT) { 448 if (strict_mode() == STRICT) {
444 if (allow_harmony_scoping()) { 449 DCHECK(var_context != kStatement);
445 if (var_context != kSourceElement && var_context != kForStatement) { 450 if (!allow_harmony_scoping()) {
446 ReportMessageAt(scanner()->peek_location(), "unprotected_const");
447 *ok = false;
448 return Statement::Default();
449 }
450 is_strict_const = true;
451 require_initializer = var_context != kForStatement;
452 } else {
453 Scanner::Location location = scanner()->peek_location(); 451 Scanner::Location location = scanner()->peek_location();
454 ReportMessageAt(location, "strict_const"); 452 ReportMessageAt(location, "strict_const");
455 *ok = false; 453 *ok = false;
456 return Statement::Default(); 454 return Statement::Default();
457 } 455 }
456 is_strict_const = true;
457 require_initializer = var_context != kForStatement;
458 } 458 }
459 } else if (peek() == Token::LET && strict_mode() == STRICT) { 459 } else if (peek() == Token::LET && strict_mode() == STRICT) {
460 Consume(Token::LET); 460 Consume(Token::LET);
461 if (var_context != kSourceElement && var_context != kForStatement) { 461 DCHECK(var_context != kStatement);
462 ReportMessageAt(scanner()->peek_location(), "unprotected_let");
463 *ok = false;
464 return Statement::Default();
465 }
466 } else { 462 } else {
467 *ok = false; 463 *ok = false;
468 return Statement::Default(); 464 return Statement::Default();
469 } 465 }
470 466
471 // The scope of a var/const declared variable anywhere inside a function 467 // The scope of a var/const declared variable anywhere inside a function
472 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 468 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
473 // of a let declared variable is the scope of the immediately enclosing 469 // of a let declared variable is the scope of the immediately enclosing
474 // block. 470 // block.
475 int nvars = 0; // the number of variables declared 471 int nvars = 0; // the number of variables declared
(...skipping 14 matching lines...) Expand all
490 if (num_decl != NULL) *num_decl = nvars; 486 if (num_decl != NULL) *num_decl = nvars;
491 return Statement::Default(); 487 return Statement::Default();
492 } 488 }
493 489
494 490
495 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 491 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
496 // ExpressionStatement | LabelledStatement :: 492 // ExpressionStatement | LabelledStatement ::
497 // Expression ';' 493 // Expression ';'
498 // Identifier ':' Statement 494 // Identifier ':' Statement
499 495
496 switch (peek()) {
497 case Token::FUNCTION:
498 case Token::LBRACE:
499 UNREACHABLE(); // Always handled by the callers.
500 case Token::CLASS:
501 ReportUnexpectedToken(Next());
502 *ok = false;
503 return Statement::Default();
504
505 // TODO(arv): Handle `let [`
506 // https://code.google.com/p/v8/issues/detail?id=3847
507
508 default:
509 break;
510 }
511
500 bool starts_with_identifier = peek_any_identifier(); 512 bool starts_with_identifier = peek_any_identifier();
501 Expression expr = ParseExpression(true, CHECK_OK); 513 Expression expr = ParseExpression(true, CHECK_OK);
502 // Even if the expression starts with an identifier, it is not necessarily an 514 // Even if the expression starts with an identifier, it is not necessarily an
503 // identifier. For example, "foo + bar" starts with an identifier but is not 515 // identifier. For example, "foo + bar" starts with an identifier but is not
504 // an identifier. 516 // an identifier.
505 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 517 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
506 // Expression is a single identifier, and not, e.g., a parenthesized 518 // Expression is a single identifier, and not, e.g., a parenthesized
507 // identifier. 519 // identifier.
508 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 520 DCHECK(!expr.AsIdentifier().IsFutureReserved());
509 DCHECK(strict_mode() == SLOPPY || 521 DCHECK(strict_mode() == SLOPPY ||
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 1027 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
1016 ParseArguments(ok); 1028 ParseArguments(ok);
1017 1029
1018 return Expression::Default(); 1030 return Expression::Default();
1019 } 1031 }
1020 1032
1021 #undef CHECK_OK 1033 #undef CHECK_OK
1022 1034
1023 1035
1024 } } // v8::internal 1036 } } // v8::internal
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698