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

Side by Side Diff: src/preparser.h

Issue 663683006: Implement ES6 Template Literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Prevent fall-through to template token handlers Created 6 years, 1 month 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 | Annotate | Revision Log
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 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 bool allow_arrow_functions() const { return allow_arrow_functions_; } 95 bool allow_arrow_functions() const { return allow_arrow_functions_; }
96 bool allow_modules() const { return scanner()->HarmonyModules(); } 96 bool allow_modules() const { return scanner()->HarmonyModules(); }
97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
98 bool allow_harmony_numeric_literals() const { 98 bool allow_harmony_numeric_literals() const {
99 return scanner()->HarmonyNumericLiterals(); 99 return scanner()->HarmonyNumericLiterals();
100 } 100 }
101 bool allow_classes() const { return scanner()->HarmonyClasses(); } 101 bool allow_classes() const { return scanner()->HarmonyClasses(); }
102 bool allow_harmony_object_literals() const { 102 bool allow_harmony_object_literals() const {
103 return allow_harmony_object_literals_; 103 return allow_harmony_object_literals_;
104 } 104 }
105 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); }
105 106
106 // Setters that determine whether certain syntactical constructs are 107 // Setters that determine whether certain syntactical constructs are
107 // allowed to be parsed by this instance of the parser. 108 // allowed to be parsed by this instance of the parser.
108 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 109 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
109 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 110 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
110 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } 111 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
111 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 112 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
112 void set_allow_harmony_scoping(bool allow) { 113 void set_allow_harmony_scoping(bool allow) {
113 scanner()->SetHarmonyScoping(allow); 114 scanner()->SetHarmonyScoping(allow);
114 } 115 }
115 void set_allow_harmony_numeric_literals(bool allow) { 116 void set_allow_harmony_numeric_literals(bool allow) {
116 scanner()->SetHarmonyNumericLiterals(allow); 117 scanner()->SetHarmonyNumericLiterals(allow);
117 } 118 }
118 void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); } 119 void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); }
119 void set_allow_harmony_object_literals(bool allow) { 120 void set_allow_harmony_object_literals(bool allow) {
120 allow_harmony_object_literals_ = allow; 121 allow_harmony_object_literals_ = allow;
121 } 122 }
123 void set_allow_harmony_templates(bool allow) {
124 scanner()->SetHarmonyTemplates(allow);
125 }
122 126
123 protected: 127 protected:
124 enum AllowEvalOrArgumentsAsIdentifier { 128 enum AllowEvalOrArgumentsAsIdentifier {
125 kAllowEvalOrArguments, 129 kAllowEvalOrArguments,
126 kDontAllowEvalOrArguments 130 kDontAllowEvalOrArguments
127 }; 131 };
128 132
129 enum Mode { 133 enum Mode {
130 PARSE_LAZILY, 134 PARSE_LAZILY,
131 PARSE_EAGERLY 135 PARSE_EAGERLY
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 492 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
489 ExpressionT ParseMemberExpression(bool* ok); 493 ExpressionT ParseMemberExpression(bool* ok);
490 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 494 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
491 bool* ok); 495 bool* ok);
492 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, 496 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
493 bool* ok); 497 bool* ok);
494 ExpressionT ParseClassLiteral(IdentifierT name, 498 ExpressionT ParseClassLiteral(IdentifierT name,
495 Scanner::Location function_name_location, 499 Scanner::Location function_name_location,
496 bool name_is_strict_reserved, int pos, 500 bool name_is_strict_reserved, int pos,
497 bool* ok); 501 bool* ok);
502 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
503 void AddTemplateSpan();
504 void AddTemplateExpression(ExpressionT);
498 505
499 // Checks if the expression is a valid reference expression (e.g., on the 506 // Checks if the expression is a valid reference expression (e.g., on the
500 // left-hand side of assignments). Although ruled out by ECMA as early errors, 507 // left-hand side of assignments). Although ruled out by ECMA as early errors,
501 // we allow calls for web compatibility and rewrite them to a runtime throw. 508 // we allow calls for web compatibility and rewrite them to a runtime throw.
502 ExpressionT CheckAndRewriteReferenceExpression( 509 ExpressionT CheckAndRewriteReferenceExpression(
503 ExpressionT expression, 510 ExpressionT expression,
504 Scanner::Location location, const char* message, bool* ok); 511 Scanner::Location location, const char* message, bool* ok);
505 512
506 // Used to detect duplicates in object literals. Each of the values 513 // Used to detect duplicates in object literals. Each of the values
507 // kGetterProperty, kSetterProperty and kValueProperty represents 514 // kGetterProperty, kSetterProperty and kValueProperty represents
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 // Utility functions 1376 // Utility functions
1370 int DeclareArrowParametersFromExpression(PreParserExpression expression, 1377 int DeclareArrowParametersFromExpression(PreParserExpression expression,
1371 PreParserScope* scope, 1378 PreParserScope* scope,
1372 Scanner::Location* dupe_loc, 1379 Scanner::Location* dupe_loc,
1373 bool* ok) { 1380 bool* ok) {
1374 // TODO(aperez): Detect duplicated identifiers in paramlists. 1381 // TODO(aperez): Detect duplicated identifiers in paramlists.
1375 *ok = expression.IsValidArrowParamList(); 1382 *ok = expression.IsValidArrowParamList();
1376 return 0; 1383 return 0;
1377 } 1384 }
1378 1385
1386 struct TemplateLiteralState {};
1387
1388 TemplateLiteralState OpenTemplateLiteral(int pos) {
1389 return TemplateLiteralState();
1390 }
1391 void AddTemplateSpan(TemplateLiteralState* state) { USE(state); }
1392 void AddTemplateExpression(TemplateLiteralState* state,
1393 PreParserExpression expression) {
1394 USE(state);
1395 USE(expression);
1396 }
1397 PreParserExpression CloseTemplateLiteral(TemplateLiteralState* state,
1398 int start, PreParserExpression tag) {
1399 USE(state);
1400 USE(start);
1401 USE(tag);
1402 return EmptyExpression();
1403 }
1404 PreParserExpression NoTemplateTag() {
1405 return PreParserExpression::Default();
1406 }
1379 static AstValueFactory* ast_value_factory() { return NULL; } 1407 static AstValueFactory* ast_value_factory() { return NULL; }
1380 1408
1381 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} 1409 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {}
1382 1410
1383 // Temporary glue; these functions will move to ParserBase. 1411 // Temporary glue; these functions will move to ParserBase.
1384 PreParserExpression ParseV8Intrinsic(bool* ok); 1412 PreParserExpression ParseV8Intrinsic(bool* ok);
1385 PreParserExpression ParseFunctionLiteral( 1413 PreParserExpression ParseFunctionLiteral(
1386 PreParserIdentifier name, Scanner::Location function_name_location, 1414 PreParserIdentifier name, Scanner::Location function_name_location,
1387 bool name_is_strict_reserved, FunctionKind kind, 1415 bool name_is_strict_reserved, FunctionKind kind,
1388 int function_token_position, FunctionLiteral::FunctionType type, 1416 int function_token_position, FunctionLiteral::FunctionType type,
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 // 'true' 1766 // 'true'
1739 // 'false' 1767 // 'false'
1740 // Identifier 1768 // Identifier
1741 // Number 1769 // Number
1742 // String 1770 // String
1743 // ArrayLiteral 1771 // ArrayLiteral
1744 // ObjectLiteral 1772 // ObjectLiteral
1745 // RegExpLiteral 1773 // RegExpLiteral
1746 // ClassLiteral 1774 // ClassLiteral
1747 // '(' Expression ')' 1775 // '(' Expression ')'
1776 // TemplateLiteral
1748 1777
1749 int pos = peek_position(); 1778 int pos = peek_position();
1750 ExpressionT result = this->EmptyExpression(); 1779 ExpressionT result = this->EmptyExpression();
1751 Token::Value token = peek(); 1780 Token::Value token = peek();
1752 switch (token) { 1781 switch (token) {
1753 case Token::THIS: { 1782 case Token::THIS: {
1754 Consume(Token::THIS); 1783 Consume(Token::THIS);
1755 scope_->RecordThisUsage(); 1784 scope_->RecordThisUsage();
1756 result = this->ThisExpression(scope_, factory()); 1785 result = this->ThisExpression(scope_, factory());
1757 break; 1786 break;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 1854 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1826 CHECK_OK); 1855 CHECK_OK);
1827 class_name_location = scanner()->location(); 1856 class_name_location = scanner()->location();
1828 } 1857 }
1829 result = this->ParseClassLiteral(name, class_name_location, 1858 result = this->ParseClassLiteral(name, class_name_location,
1830 is_strict_reserved_name, 1859 is_strict_reserved_name,
1831 class_token_position, CHECK_OK); 1860 class_token_position, CHECK_OK);
1832 break; 1861 break;
1833 } 1862 }
1834 1863
1864 case Token::TEMPLATE_SPAN:
1865 case Token::TEMPLATE_TAIL:
1866 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), pos,
1867 CHECK_OK);
1868 break;
1869
1835 case Token::MOD: 1870 case Token::MOD:
1836 if (allow_natives_syntax() || extension_ != NULL) { 1871 if (allow_natives_syntax() || extension_ != NULL) {
1837 result = this->ParseV8Intrinsic(CHECK_OK); 1872 result = this->ParseV8Intrinsic(CHECK_OK);
1838 break; 1873 break;
1839 } 1874 }
1840 // If we're not allowing special syntax we fall-through to the 1875 // If we're not allowing special syntax we fall-through to the
1841 // default case. 1876 // default case.
1842 1877
1843 default: { 1878 default: {
1844 Next(); 1879 Next();
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 // direct eval calls. These calls are all of the form eval(...), with 2471 // direct eval calls. These calls are all of the form eval(...), with
2437 // no explicit receiver. 2472 // no explicit receiver.
2438 // These calls are marked as potentially direct eval calls. Whether 2473 // These calls are marked as potentially direct eval calls. Whether
2439 // they are actually direct calls to eval is determined at run time. 2474 // they are actually direct calls to eval is determined at run time.
2440 this->CheckPossibleEvalCall(result, scope_); 2475 this->CheckPossibleEvalCall(result, scope_);
2441 result = factory()->NewCall(result, args, pos); 2476 result = factory()->NewCall(result, args, pos);
2442 if (fni_ != NULL) fni_->RemoveLastFunction(); 2477 if (fni_ != NULL) fni_->RemoveLastFunction();
2443 break; 2478 break;
2444 } 2479 }
2445 2480
2481 case Token::TEMPLATE_SPAN:
2482 case Token::TEMPLATE_TAIL: {
2483 int pos;
2484 if (scanner()->current_token() == Token::IDENTIFIER) {
2485 pos = position();
2486 } else {
2487 pos = peek_position();
2488 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
2489 result->AsFunctionLiteral()->set_parenthesized();
2490 }
2491 }
2492 result = ParseTemplateLiteral(result, pos, CHECK_OK);
2493 break;
2494 }
2495
2446 case Token::PERIOD: { 2496 case Token::PERIOD: {
2447 Consume(Token::PERIOD); 2497 Consume(Token::PERIOD);
2448 int pos = position(); 2498 int pos = position();
2449 IdentifierT name = ParseIdentifierName(CHECK_OK); 2499 IdentifierT name = ParseIdentifierName(CHECK_OK);
2450 result = factory()->NewProperty( 2500 result = factory()->NewProperty(
2451 result, factory()->NewStringLiteral(name, pos), pos); 2501 result, factory()->NewStringLiteral(name, pos), pos);
2452 if (fni_ != NULL) this->PushLiteralName(fni_, name); 2502 if (fni_ != NULL) this->PushLiteralName(fni_, name);
2453 break; 2503 break;
2454 } 2504 }
2455 2505
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
2774 int end_pos = peek_position(); 2824 int end_pos = peek_position();
2775 Expect(Token::RBRACE, CHECK_OK); 2825 Expect(Token::RBRACE, CHECK_OK);
2776 2826
2777 return this->ClassExpression(name, extends, constructor, properties, pos, 2827 return this->ClassExpression(name, extends, constructor, properties, pos,
2778 end_pos + 1, factory()); 2828 end_pos + 1, factory());
2779 } 2829 }
2780 2830
2781 2831
2782 template <typename Traits> 2832 template <typename Traits>
2783 typename ParserBase<Traits>::ExpressionT 2833 typename ParserBase<Traits>::ExpressionT
2834 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) {
2835 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
2836
2837 // Add TV / TRV
2838 if (peek() == Token::TEMPLATE_SPAN) {
2839 Consume(Token::TEMPLATE_SPAN);
2840 int pos = position();
2841 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
2842 Traits::AddTemplateSpan(&ts);
2843
2844 for (;;) {
2845 Token::Value next = peek();
2846 if (next < 0) {
2847 ReportMessage("unterminated_template");
2848 *ok = false;
2849 return Traits::EmptyExpression();
2850 }
2851
2852 // Parse an Expression
2853 ExpressionT expression = this->ParseExpression(false, CHECK_OK);
2854 Traits::AddTemplateExpression(&ts, expression);
2855
2856 // If we didn't die parsing that expression, our next token should be a
2857 // TEMPLATE_SPAN or
2858 // TEMPLATE_TAIL.
2859 next = scanner()->ScanTemplateSpan();
2860 Next();
2861
2862 if (next == Token::ILLEGAL || next < 0) {
2863 ReportMessage("unterminated_template");
2864 *ok = false;
2865 return Traits::EmptyExpression();
2866 }
2867
2868 CHECK(next == Token::TEMPLATE_SPAN || next == Token::TEMPLATE_TAIL);
2869 Traits::AddTemplateSpan(&ts);
2870
2871 if (next == Token::TEMPLATE_TAIL) {
2872 break;
2873 }
2874 }
2875 return Traits::CloseTemplateLiteral(&ts, start, tag);
2876 }
2877 Consume(Token::TEMPLATE_TAIL);
2878 int pos = position();
2879 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
2880 Traits::AddTemplateSpan(&ts);
2881 return Traits::CloseTemplateLiteral(&ts, start, tag);
2882 }
2883
2884
2885 template <typename Traits>
2886 typename ParserBase<Traits>::ExpressionT
2784 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2887 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2785 ExpressionT expression, 2888 ExpressionT expression,
2786 Scanner::Location location, const char* message, bool* ok) { 2889 Scanner::Location location, const char* message, bool* ok) {
2787 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2890 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2788 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2891 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2789 this->ReportMessageAt(location, "strict_eval_arguments", false); 2892 this->ReportMessageAt(location, "strict_eval_arguments", false);
2790 *ok = false; 2893 *ok = false;
2791 return this->EmptyExpression(); 2894 return this->EmptyExpression();
2792 } else if (expression->IsValidReferenceExpression()) { 2895 } else if (expression->IsValidReferenceExpression()) {
2793 return expression; 2896 return expression;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2831 DCHECK(IsAccessorAccessorConflict(old_type, type)); 2934 DCHECK(IsAccessorAccessorConflict(old_type, type));
2832 // Both accessors of the same type. 2935 // Both accessors of the same type.
2833 parser()->ReportMessage("accessor_get_set"); 2936 parser()->ReportMessage("accessor_get_set");
2834 } 2937 }
2835 *ok = false; 2938 *ok = false;
2836 } 2939 }
2837 } 2940 }
2838 } } // v8::internal 2941 } } // v8::internal
2839 2942
2840 #endif // V8_PREPARSER_H 2943 #endif // V8_PREPARSER_H
OLDNEW
« src/parser.cc ('K') | « src/parser.cc ('k') | src/prettyprinter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698