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 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
487 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 491 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
488 ExpressionT ParseMemberExpression(bool* ok); | 492 ExpressionT ParseMemberExpression(bool* ok); |
489 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 493 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
490 bool* ok); | 494 bool* ok); |
491 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, | 495 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast, |
492 bool* ok); | 496 bool* ok); |
493 ExpressionT ParseClassLiteral(IdentifierT name, | 497 ExpressionT ParseClassLiteral(IdentifierT name, |
494 Scanner::Location function_name_location, | 498 Scanner::Location function_name_location, |
495 bool name_is_strict_reserved, int pos, | 499 bool name_is_strict_reserved, int pos, |
496 bool* ok); | 500 bool* ok); |
501 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | |
502 void AddTemplateSpan(); | |
503 void AddTemplateExpression(ExpressionT); | |
497 | 504 |
498 // Checks if the expression is a valid reference expression (e.g., on the | 505 // Checks if the expression is a valid reference expression (e.g., on the |
499 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 506 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
500 // we allow calls for web compatibility and rewrite them to a runtime throw. | 507 // we allow calls for web compatibility and rewrite them to a runtime throw. |
501 ExpressionT CheckAndRewriteReferenceExpression( | 508 ExpressionT CheckAndRewriteReferenceExpression( |
502 ExpressionT expression, | 509 ExpressionT expression, |
503 Scanner::Location location, const char* message, bool* ok); | 510 Scanner::Location location, const char* message, bool* ok); |
504 | 511 |
505 // Used to detect duplicates in object literals. Each of the values | 512 // Used to detect duplicates in object literals. Each of the values |
506 // kGetterProperty, kSetterProperty and kValueProperty represents | 513 // kGetterProperty, kSetterProperty and kValueProperty represents |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1372 // Utility functions | 1379 // Utility functions |
1373 int DeclareArrowParametersFromExpression(PreParserExpression expression, | 1380 int DeclareArrowParametersFromExpression(PreParserExpression expression, |
1374 PreParserScope* scope, | 1381 PreParserScope* scope, |
1375 Scanner::Location* dupe_loc, | 1382 Scanner::Location* dupe_loc, |
1376 bool* ok) { | 1383 bool* ok) { |
1377 // TODO(aperez): Detect duplicated identifiers in paramlists. | 1384 // TODO(aperez): Detect duplicated identifiers in paramlists. |
1378 *ok = expression.IsValidArrowParamList(); | 1385 *ok = expression.IsValidArrowParamList(); |
1379 return 0; | 1386 return 0; |
1380 } | 1387 } |
1381 | 1388 |
1389 struct TemplateLiteralState {}; | |
1390 | |
1391 TemplateLiteralState OpenTemplateLiteral(int pos) { | |
1392 return TemplateLiteralState(); | |
1393 } | |
1394 void AddTemplateSpan(TemplateLiteralState* state) { USE(state); } | |
1395 void AddTemplateExpression(TemplateLiteralState* state, | |
1396 PreParserExpression expression) { | |
1397 USE(state); | |
1398 USE(expression); | |
1399 } | |
1400 PreParserExpression CloseTemplateLiteral(TemplateLiteralState* state, | |
1401 int start, PreParserExpression tag) { | |
1402 USE(state); | |
1403 USE(start); | |
1404 USE(tag); | |
1405 return EmptyExpression(); | |
1406 } | |
1407 PreParserExpression NoTemplateTag() { | |
1408 return PreParserExpression::Default(); | |
1409 } | |
1382 static AstValueFactory* ast_value_factory() { return NULL; } | 1410 static AstValueFactory* ast_value_factory() { return NULL; } |
1383 | 1411 |
1384 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} | 1412 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {} |
1385 | 1413 |
1386 // Temporary glue; these functions will move to ParserBase. | 1414 // Temporary glue; these functions will move to ParserBase. |
1387 PreParserExpression ParseV8Intrinsic(bool* ok); | 1415 PreParserExpression ParseV8Intrinsic(bool* ok); |
1388 PreParserExpression ParseFunctionLiteral( | 1416 PreParserExpression ParseFunctionLiteral( |
1389 PreParserIdentifier name, Scanner::Location function_name_location, | 1417 PreParserIdentifier name, Scanner::Location function_name_location, |
1390 bool name_is_strict_reserved, FunctionKind kind, | 1418 bool name_is_strict_reserved, FunctionKind kind, |
1391 int function_token_position, FunctionLiteral::FunctionType type, | 1419 int function_token_position, FunctionLiteral::FunctionType type, |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1742 // 'true' | 1770 // 'true' |
1743 // 'false' | 1771 // 'false' |
1744 // Identifier | 1772 // Identifier |
1745 // Number | 1773 // Number |
1746 // String | 1774 // String |
1747 // ArrayLiteral | 1775 // ArrayLiteral |
1748 // ObjectLiteral | 1776 // ObjectLiteral |
1749 // RegExpLiteral | 1777 // RegExpLiteral |
1750 // ClassLiteral | 1778 // ClassLiteral |
1751 // '(' Expression ')' | 1779 // '(' Expression ')' |
1780 // TemplateLiteral | |
1752 | 1781 |
1753 int pos = peek_position(); | 1782 int pos = peek_position(); |
1754 ExpressionT result = this->EmptyExpression(); | 1783 ExpressionT result = this->EmptyExpression(); |
1755 Token::Value token = peek(); | 1784 Token::Value token = peek(); |
1756 switch (token) { | 1785 switch (token) { |
1757 case Token::THIS: { | 1786 case Token::THIS: { |
1758 Consume(Token::THIS); | 1787 Consume(Token::THIS); |
1759 scope_->RecordThisUsage(); | 1788 scope_->RecordThisUsage(); |
1760 result = this->ThisExpression(scope_, factory()); | 1789 result = this->ThisExpression(scope_, factory()); |
1761 break; | 1790 break; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1830 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 1859 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
1831 CHECK_OK); | 1860 CHECK_OK); |
1832 class_name_location = scanner()->location(); | 1861 class_name_location = scanner()->location(); |
1833 } | 1862 } |
1834 result = this->ParseClassLiteral(name, class_name_location, | 1863 result = this->ParseClassLiteral(name, class_name_location, |
1835 is_strict_reserved_name, | 1864 is_strict_reserved_name, |
1836 class_token_position, CHECK_OK); | 1865 class_token_position, CHECK_OK); |
1837 break; | 1866 break; |
1838 } | 1867 } |
1839 | 1868 |
1869 case Token::TEMPLATE_SPAN: | |
1870 case Token::TEMPLATE_TAIL: | |
1871 result = this->ParseTemplateLiteral(Traits::NoTemplateTag(), pos, | |
1872 CHECK_OK); | |
1873 break; | |
1874 | |
1840 case Token::MOD: | 1875 case Token::MOD: |
1841 if (allow_natives_syntax() || extension_ != NULL) { | 1876 if (allow_natives_syntax() || extension_ != NULL) { |
1842 result = this->ParseV8Intrinsic(CHECK_OK); | 1877 result = this->ParseV8Intrinsic(CHECK_OK); |
1843 break; | 1878 break; |
1844 } | 1879 } |
1845 // If we're not allowing special syntax we fall-through to the | 1880 // If we're not allowing special syntax we fall-through to the |
1846 // default case. | 1881 // default case. |
1847 | 1882 |
1848 default: { | 1883 default: { |
1849 Next(); | 1884 Next(); |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2453 // direct eval calls. These calls are all of the form eval(...), with | 2488 // direct eval calls. These calls are all of the form eval(...), with |
2454 // no explicit receiver. | 2489 // no explicit receiver. |
2455 // These calls are marked as potentially direct eval calls. Whether | 2490 // These calls are marked as potentially direct eval calls. Whether |
2456 // they are actually direct calls to eval is determined at run time. | 2491 // they are actually direct calls to eval is determined at run time. |
2457 this->CheckPossibleEvalCall(result, scope_); | 2492 this->CheckPossibleEvalCall(result, scope_); |
2458 result = factory()->NewCall(result, args, pos); | 2493 result = factory()->NewCall(result, args, pos); |
2459 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2494 if (fni_ != NULL) fni_->RemoveLastFunction(); |
2460 break; | 2495 break; |
2461 } | 2496 } |
2462 | 2497 |
2498 case Token::TEMPLATE_SPAN: | |
2499 case Token::TEMPLATE_TAIL: { | |
2500 int pos; | |
2501 if (scanner()->current_token() == Token::IDENTIFIER) { | |
2502 pos = position(); | |
2503 } else { | |
2504 pos = peek_position(); | |
2505 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | |
2506 result->AsFunctionLiteral()->set_parenthesized(); | |
marja
2014/11/10 15:32:02
Why?
caitp (gmail)
2014/11/10 15:43:56
It's basically copy/pasted from the MemberExpressi
marja
2014/11/11 09:15:36
I dug up a bit where this is coming from. In any c
| |
2507 } | |
2508 } | |
2509 result = ParseTemplateLiteral(result, pos, CHECK_OK); | |
2510 break; | |
2511 } | |
2512 | |
2463 case Token::PERIOD: { | 2513 case Token::PERIOD: { |
2464 Consume(Token::PERIOD); | 2514 Consume(Token::PERIOD); |
2465 int pos = position(); | 2515 int pos = position(); |
2466 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2516 IdentifierT name = ParseIdentifierName(CHECK_OK); |
2467 result = factory()->NewProperty( | 2517 result = factory()->NewProperty( |
2468 result, factory()->NewStringLiteral(name, pos), pos); | 2518 result, factory()->NewStringLiteral(name, pos), pos); |
2469 if (fni_ != NULL) this->PushLiteralName(fni_, name); | 2519 if (fni_ != NULL) this->PushLiteralName(fni_, name); |
2470 break; | 2520 break; |
2471 } | 2521 } |
2472 | 2522 |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2791 int end_pos = peek_position(); | 2841 int end_pos = peek_position(); |
2792 Expect(Token::RBRACE, CHECK_OK); | 2842 Expect(Token::RBRACE, CHECK_OK); |
2793 | 2843 |
2794 return this->ClassExpression(name, extends, constructor, properties, pos, | 2844 return this->ClassExpression(name, extends, constructor, properties, pos, |
2795 end_pos + 1, factory()); | 2845 end_pos + 1, factory()); |
2796 } | 2846 } |
2797 | 2847 |
2798 | 2848 |
2799 template <typename Traits> | 2849 template <typename Traits> |
2800 typename ParserBase<Traits>::ExpressionT | 2850 typename ParserBase<Traits>::ExpressionT |
2851 ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) { | |
marja
2014/11/10 15:32:02
Can you add here a comment about the parse rules w
| |
2852 CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL); | |
2853 | |
2854 // Add TV / TRV | |
2855 if (peek() == Token::TEMPLATE_SPAN) { | |
2856 Consume(Token::TEMPLATE_SPAN); | |
2857 int pos = position(); | |
2858 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos); | |
2859 Traits::AddTemplateSpan(&ts); | |
2860 | |
2861 for (;;) { | |
2862 Token::Value next = peek(); | |
2863 if (next < 0) { | |
2864 ReportMessage("unterminated_template"); | |
2865 *ok = false; | |
2866 return Traits::EmptyExpression(); | |
2867 } | |
2868 | |
2869 // Parse an Expression | |
2870 ExpressionT expression = this->ParseExpression(false, CHECK_OK); | |
marja
2014/11/10 15:32:02
Why expression? Are we now inside the ${... or...
caitp (gmail)
2014/11/10 15:43:56
Yeah, if we get a TEMPLATE_SPAN token, then we jus
| |
2871 Traits::AddTemplateExpression(&ts, expression); | |
2872 | |
2873 // If we didn't die parsing that expression, our next token should be a | |
2874 // TEMPLATE_SPAN or | |
2875 // TEMPLATE_TAIL. | |
2876 next = scanner()->ScanTemplateSpan(); | |
2877 Next(); | |
2878 | |
2879 if (next == Token::ILLEGAL || next < 0) { | |
2880 ReportMessage("unterminated_template"); | |
2881 *ok = false; | |
2882 return Traits::EmptyExpression(); | |
2883 } | |
2884 | |
2885 CHECK(next == Token::TEMPLATE_SPAN || next == Token::TEMPLATE_TAIL); | |
2886 Traits::AddTemplateSpan(&ts); | |
2887 | |
2888 if (next == Token::TEMPLATE_TAIL) { | |
2889 break; | |
2890 } | |
2891 } | |
2892 return Traits::CloseTemplateLiteral(&ts, start, tag); | |
2893 } | |
2894 Consume(Token::TEMPLATE_TAIL); | |
2895 int pos = position(); | |
2896 typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos); | |
2897 Traits::AddTemplateSpan(&ts); | |
2898 return Traits::CloseTemplateLiteral(&ts, start, tag); | |
2899 } | |
2900 | |
2901 | |
2902 template <typename Traits> | |
2903 typename ParserBase<Traits>::ExpressionT | |
2801 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2904 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2802 ExpressionT expression, | 2905 ExpressionT expression, |
2803 Scanner::Location location, const char* message, bool* ok) { | 2906 Scanner::Location location, const char* message, bool* ok) { |
2804 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2907 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2805 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2908 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2806 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2909 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2807 *ok = false; | 2910 *ok = false; |
2808 return this->EmptyExpression(); | 2911 return this->EmptyExpression(); |
2809 } else if (expression->IsValidReferenceExpression()) { | 2912 } else if (expression->IsValidReferenceExpression()) { |
2810 return expression; | 2913 return expression; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2848 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2951 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2849 // Both accessors of the same type. | 2952 // Both accessors of the same type. |
2850 parser()->ReportMessage("accessor_get_set"); | 2953 parser()->ReportMessage("accessor_get_set"); |
2851 } | 2954 } |
2852 *ok = false; | 2955 *ok = false; |
2853 } | 2956 } |
2854 } | 2957 } |
2855 } } // v8::internal | 2958 } } // v8::internal |
2856 | 2959 |
2857 #endif // V8_PREPARSER_H | 2960 #endif // V8_PREPARSER_H |
OLD | NEW |