OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 } | 1862 } |
1834 | 1863 |
1835 case Token::MOD: | 1864 case Token::MOD: |
1836 if (allow_natives_syntax() || extension_ != NULL) { | 1865 if (allow_natives_syntax() || extension_ != NULL) { |
1837 result = this->ParseV8Intrinsic(CHECK_OK); | 1866 result = this->ParseV8Intrinsic(CHECK_OK); |
1838 break; | 1867 break; |
1839 } | 1868 } |
1840 // If we're not allowing special syntax we fall-through to the | 1869 // If we're not allowing special syntax we fall-through to the |
1841 // default case. | 1870 // default case. |
1842 | 1871 |
| 1872 case Token::TEMPLATE_SPAN: |
| 1873 case Token::TEMPLATE_TAIL: |
| 1874 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), pos, |
| 1875 CHECK_OK); |
| 1876 break; |
| 1877 |
1843 default: { | 1878 default: { |
1844 Next(); | 1879 Next(); |
1845 ReportUnexpectedToken(token); | 1880 ReportUnexpectedToken(token); |
1846 *ok = false; | 1881 *ok = false; |
1847 } | 1882 } |
1848 } | 1883 } |
1849 | 1884 |
1850 return result; | 1885 return result; |
1851 } | 1886 } |
1852 | 1887 |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |