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/bailout-reason.h" | 8 #include "src/bailout-reason.h" |
9 #include "src/expression-classifier.h" | 9 #include "src/expression-classifier.h" |
10 #include "src/func-name-inferrer.h" | 10 #include "src/func-name-inferrer.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 allow_harmony_sloppy_function_(false), | 112 allow_harmony_sloppy_function_(false), |
113 allow_harmony_sloppy_let_(false), | 113 allow_harmony_sloppy_let_(false), |
114 allow_harmony_rest_parameters_(false), | 114 allow_harmony_rest_parameters_(false), |
115 allow_harmony_default_parameters_(false), | 115 allow_harmony_default_parameters_(false), |
116 allow_harmony_spread_calls_(false), | 116 allow_harmony_spread_calls_(false), |
117 allow_harmony_destructuring_(false), | 117 allow_harmony_destructuring_(false), |
118 allow_harmony_spread_arrays_(false), | 118 allow_harmony_spread_arrays_(false), |
119 allow_harmony_new_target_(false), | 119 allow_harmony_new_target_(false), |
120 allow_strong_mode_(false), | 120 allow_strong_mode_(false), |
121 allow_legacy_const_(true), | 121 allow_legacy_const_(true), |
122 allow_harmony_do_expressions_(false) {} | 122 allow_harmony_do_expressions_(false), |
| 123 allow_harmony_async_await_(false) {} |
123 | 124 |
124 #define ALLOW_ACCESSORS(name) \ | 125 #define ALLOW_ACCESSORS(name) \ |
125 bool allow_##name() const { return allow_##name##_; } \ | 126 bool allow_##name() const { return allow_##name##_; } \ |
126 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 127 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
127 | 128 |
128 ALLOW_ACCESSORS(lazy); | 129 ALLOW_ACCESSORS(lazy); |
129 ALLOW_ACCESSORS(natives); | 130 ALLOW_ACCESSORS(natives); |
130 ALLOW_ACCESSORS(harmony_sloppy); | 131 ALLOW_ACCESSORS(harmony_sloppy); |
131 ALLOW_ACCESSORS(harmony_sloppy_function); | 132 ALLOW_ACCESSORS(harmony_sloppy_function); |
132 ALLOW_ACCESSORS(harmony_sloppy_let); | 133 ALLOW_ACCESSORS(harmony_sloppy_let); |
133 ALLOW_ACCESSORS(harmony_rest_parameters); | 134 ALLOW_ACCESSORS(harmony_rest_parameters); |
134 ALLOW_ACCESSORS(harmony_default_parameters); | 135 ALLOW_ACCESSORS(harmony_default_parameters); |
135 ALLOW_ACCESSORS(harmony_spread_calls); | 136 ALLOW_ACCESSORS(harmony_spread_calls); |
136 ALLOW_ACCESSORS(harmony_destructuring); | 137 ALLOW_ACCESSORS(harmony_destructuring); |
137 ALLOW_ACCESSORS(harmony_spread_arrays); | 138 ALLOW_ACCESSORS(harmony_spread_arrays); |
138 ALLOW_ACCESSORS(harmony_new_target); | 139 ALLOW_ACCESSORS(harmony_new_target); |
139 ALLOW_ACCESSORS(strong_mode); | 140 ALLOW_ACCESSORS(strong_mode); |
140 ALLOW_ACCESSORS(legacy_const); | 141 ALLOW_ACCESSORS(legacy_const); |
141 ALLOW_ACCESSORS(harmony_do_expressions); | 142 ALLOW_ACCESSORS(harmony_do_expressions); |
| 143 ALLOW_ACCESSORS(harmony_async_await); |
142 #undef ALLOW_ACCESSORS | 144 #undef ALLOW_ACCESSORS |
143 | 145 |
144 uintptr_t stack_limit() const { return stack_limit_; } | 146 uintptr_t stack_limit() const { return stack_limit_; } |
145 | 147 |
146 protected: | 148 protected: |
147 enum AllowRestrictedIdentifiers { | 149 enum AllowRestrictedIdentifiers { |
148 kAllowRestrictedIdentifiers, | 150 kAllowRestrictedIdentifiers, |
149 kDontAllowRestrictedIdentifiers | 151 kDontAllowRestrictedIdentifiers |
150 }; | 152 }; |
151 | 153 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 this_location_ = location; | 211 this_location_ = location; |
210 } | 212 } |
211 void set_super_location(Scanner::Location location) { | 213 void set_super_location(Scanner::Location location) { |
212 super_location_ = location; | 214 super_location_ = location; |
213 } | 215 } |
214 void set_return_location(Scanner::Location location) { | 216 void set_return_location(Scanner::Location location) { |
215 return_location_ = location; | 217 return_location_ = location; |
216 } | 218 } |
217 | 219 |
218 bool is_generator() const { return IsGeneratorFunction(kind_); } | 220 bool is_generator() const { return IsGeneratorFunction(kind_); } |
| 221 bool is_async() const { return IsAsyncFunction(kind_); } |
219 | 222 |
220 FunctionKind kind() const { return kind_; } | 223 FunctionKind kind() const { return kind_; } |
221 FunctionState* outer() const { return outer_function_state_; } | 224 FunctionState* outer() const { return outer_function_state_; } |
222 | 225 |
223 void set_generator_object_variable( | 226 void set_generator_object_variable( |
224 typename Traits::Type::GeneratorVariable* variable) { | 227 typename Traits::Type::GeneratorVariable* variable) { |
225 DCHECK(variable != NULL); | 228 DCHECK(variable != NULL); |
226 DCHECK(is_generator()); | 229 DCHECK(is_generator()); |
227 generator_object_variable_ = variable; | 230 generator_object_variable_ = variable; |
228 } | 231 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 tok == Token::EOS) { | 398 tok == Token::EOS) { |
396 return; | 399 return; |
397 } | 400 } |
398 Expect(Token::SEMICOLON, ok); | 401 Expect(Token::SEMICOLON, ok); |
399 } | 402 } |
400 | 403 |
401 bool peek_any_identifier() { | 404 bool peek_any_identifier() { |
402 Token::Value next = peek(); | 405 Token::Value next = peek(); |
403 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || | 406 return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD || |
404 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 407 next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
405 next == Token::STATIC || next == Token::YIELD; | 408 next == Token::STATIC || next == Token::YIELD || |
| 409 next == Token::ASYNC; |
406 } | 410 } |
407 | 411 |
408 bool CheckContextualKeyword(Vector<const char> keyword) { | 412 bool CheckContextualKeyword(Vector<const char> keyword) { |
409 if (PeekContextualKeyword(keyword)) { | 413 if (PeekContextualKeyword(keyword)) { |
410 Consume(Token::IDENTIFIER); | 414 Consume(Token::IDENTIFIER); |
411 return true; | 415 return true; |
412 } | 416 } |
413 return false; | 417 return false; |
414 } | 418 } |
415 | 419 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 return 0; // 0 precedence will terminate binary expression parsing | 506 return 0; // 0 precedence will terminate binary expression parsing |
503 return Token::Precedence(token); | 507 return Token::Precedence(token); |
504 } | 508 } |
505 | 509 |
506 typename Traits::Type::Factory* factory() { | 510 typename Traits::Type::Factory* factory() { |
507 return function_state_->factory(); | 511 return function_state_->factory(); |
508 } | 512 } |
509 | 513 |
510 LanguageMode language_mode() { return scope_->language_mode(); } | 514 LanguageMode language_mode() { return scope_->language_mode(); } |
511 bool is_generator() const { return function_state_->is_generator(); } | 515 bool is_generator() const { return function_state_->is_generator(); } |
| 516 bool is_async() const { return function_state_->is_async(); } |
512 | 517 |
513 bool allow_const() { | 518 bool allow_const() { |
514 return is_strict(language_mode()) || allow_harmony_sloppy() || | 519 return is_strict(language_mode()) || allow_harmony_sloppy() || |
515 allow_legacy_const(); | 520 allow_legacy_const(); |
516 } | 521 } |
517 | 522 |
518 bool allow_let() { | 523 bool allow_let() { |
519 return is_strict(language_mode()) || allow_harmony_sloppy_let(); | 524 return is_strict(language_mode()) || allow_harmony_sloppy_let(); |
520 } | 525 } |
521 | 526 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 | 741 |
737 void ParseFormalParameter(FormalParametersT* parameters, | 742 void ParseFormalParameter(FormalParametersT* parameters, |
738 ExpressionClassifier* classifier, bool* ok); | 743 ExpressionClassifier* classifier, bool* ok); |
739 void ParseFormalParameterList(FormalParametersT* parameters, | 744 void ParseFormalParameterList(FormalParametersT* parameters, |
740 ExpressionClassifier* classifier, bool* ok); | 745 ExpressionClassifier* classifier, bool* ok); |
741 void CheckArityRestrictions( | 746 void CheckArityRestrictions( |
742 int param_count, FunctionLiteral::ArityRestriction arity_restriction, | 747 int param_count, FunctionLiteral::ArityRestriction arity_restriction, |
743 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); | 748 bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok); |
744 | 749 |
745 bool IsNextLetKeyword(); | 750 bool IsNextLetKeyword(); |
| 751 bool IsNextAsyncFunctionKeyword(); |
746 | 752 |
747 // Checks if the expression is a valid reference expression (e.g., on the | 753 // Checks if the expression is a valid reference expression (e.g., on the |
748 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 754 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
749 // we allow calls for web compatibility and rewrite them to a runtime throw. | 755 // we allow calls for web compatibility and rewrite them to a runtime throw. |
750 ExpressionT CheckAndRewriteReferenceExpression( | 756 ExpressionT CheckAndRewriteReferenceExpression( |
751 ExpressionT expression, int beg_pos, int end_pos, | 757 ExpressionT expression, int beg_pos, int end_pos, |
752 MessageTemplate::Template message, bool* ok); | 758 MessageTemplate::Template message, bool* ok); |
753 ExpressionT CheckAndRewriteReferenceExpression( | 759 ExpressionT CheckAndRewriteReferenceExpression( |
754 ExpressionT expression, int beg_pos, int end_pos, | 760 ExpressionT expression, int beg_pos, int end_pos, |
755 MessageTemplate::Template message, ParseErrorType type, bool* ok); | 761 MessageTemplate::Template message, ParseErrorType type, bool* ok); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 bool allow_harmony_sloppy_let_; | 847 bool allow_harmony_sloppy_let_; |
842 bool allow_harmony_rest_parameters_; | 848 bool allow_harmony_rest_parameters_; |
843 bool allow_harmony_default_parameters_; | 849 bool allow_harmony_default_parameters_; |
844 bool allow_harmony_spread_calls_; | 850 bool allow_harmony_spread_calls_; |
845 bool allow_harmony_destructuring_; | 851 bool allow_harmony_destructuring_; |
846 bool allow_harmony_spread_arrays_; | 852 bool allow_harmony_spread_arrays_; |
847 bool allow_harmony_new_target_; | 853 bool allow_harmony_new_target_; |
848 bool allow_strong_mode_; | 854 bool allow_strong_mode_; |
849 bool allow_legacy_const_; | 855 bool allow_legacy_const_; |
850 bool allow_harmony_do_expressions_; | 856 bool allow_harmony_do_expressions_; |
| 857 bool allow_harmony_async_await_; |
851 }; | 858 }; |
852 | 859 |
853 | 860 |
854 class PreParserIdentifier { | 861 class PreParserIdentifier { |
855 public: | 862 public: |
856 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 863 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
857 static PreParserIdentifier Default() { | 864 static PreParserIdentifier Default() { |
858 return PreParserIdentifier(kUnknownIdentifier); | 865 return PreParserIdentifier(kUnknownIdentifier); |
859 } | 866 } |
860 static PreParserIdentifier Eval() { | 867 static PreParserIdentifier Eval() { |
(...skipping 13 matching lines...) Expand all Loading... |
874 } | 881 } |
875 static PreParserIdentifier Let() { | 882 static PreParserIdentifier Let() { |
876 return PreParserIdentifier(kLetIdentifier); | 883 return PreParserIdentifier(kLetIdentifier); |
877 } | 884 } |
878 static PreParserIdentifier Static() { | 885 static PreParserIdentifier Static() { |
879 return PreParserIdentifier(kStaticIdentifier); | 886 return PreParserIdentifier(kStaticIdentifier); |
880 } | 887 } |
881 static PreParserIdentifier Yield() { | 888 static PreParserIdentifier Yield() { |
882 return PreParserIdentifier(kYieldIdentifier); | 889 return PreParserIdentifier(kYieldIdentifier); |
883 } | 890 } |
| 891 static PreParserIdentifier Async() { |
| 892 return PreParserIdentifier(kAsyncIdentifier); |
| 893 } |
884 static PreParserIdentifier Prototype() { | 894 static PreParserIdentifier Prototype() { |
885 return PreParserIdentifier(kPrototypeIdentifier); | 895 return PreParserIdentifier(kPrototypeIdentifier); |
886 } | 896 } |
887 static PreParserIdentifier Constructor() { | 897 static PreParserIdentifier Constructor() { |
888 return PreParserIdentifier(kConstructorIdentifier); | 898 return PreParserIdentifier(kConstructorIdentifier); |
889 } | 899 } |
890 bool IsEval() const { return type_ == kEvalIdentifier; } | 900 bool IsEval() const { return type_ == kEvalIdentifier; } |
891 bool IsArguments() const { return type_ == kArgumentsIdentifier; } | 901 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
892 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } | 902 bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } |
893 bool IsUndefined() const { return type_ == kUndefinedIdentifier; } | 903 bool IsUndefined() const { return type_ == kUndefinedIdentifier; } |
894 bool IsLet() const { return type_ == kLetIdentifier; } | 904 bool IsLet() const { return type_ == kLetIdentifier; } |
895 bool IsStatic() const { return type_ == kStaticIdentifier; } | 905 bool IsStatic() const { return type_ == kStaticIdentifier; } |
896 bool IsYield() const { return type_ == kYieldIdentifier; } | 906 bool IsYield() const { return type_ == kYieldIdentifier; } |
| 907 bool IsAsync() const { return type_ == kAsyncIdentifier; } |
897 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } | 908 bool IsPrototype() const { return type_ == kPrototypeIdentifier; } |
898 bool IsConstructor() const { return type_ == kConstructorIdentifier; } | 909 bool IsConstructor() const { return type_ == kConstructorIdentifier; } |
899 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } | 910 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
900 bool IsFutureStrictReserved() const { | 911 bool IsFutureStrictReserved() const { |
901 return type_ == kFutureStrictReservedIdentifier || | 912 return type_ == kFutureStrictReservedIdentifier || |
902 type_ == kLetIdentifier || type_ == kStaticIdentifier || | 913 type_ == kLetIdentifier || type_ == kStaticIdentifier || |
903 type_ == kYieldIdentifier; | 914 type_ == kYieldIdentifier; |
904 } | 915 } |
905 | 916 |
906 // Allow identifier->name()[->length()] to work. The preparser | 917 // Allow identifier->name()[->length()] to work. The preparser |
907 // does not need the actual positions/lengths of the identifiers. | 918 // does not need the actual positions/lengths of the identifiers. |
908 const PreParserIdentifier* operator->() const { return this; } | 919 const PreParserIdentifier* operator->() const { return this; } |
909 const PreParserIdentifier raw_name() const { return *this; } | 920 const PreParserIdentifier raw_name() const { return *this; } |
910 | 921 |
911 int position() const { return 0; } | 922 int position() const { return 0; } |
912 int length() const { return 0; } | 923 int length() const { return 0; } |
913 | 924 |
914 private: | 925 private: |
915 enum Type { | 926 enum Type { |
916 kUnknownIdentifier, | 927 kUnknownIdentifier, |
917 kFutureReservedIdentifier, | 928 kFutureReservedIdentifier, |
918 kFutureStrictReservedIdentifier, | 929 kFutureStrictReservedIdentifier, |
919 kLetIdentifier, | 930 kLetIdentifier, |
920 kStaticIdentifier, | 931 kStaticIdentifier, |
921 kYieldIdentifier, | 932 kYieldIdentifier, |
| 933 kAsyncIdentifier, |
922 kEvalIdentifier, | 934 kEvalIdentifier, |
923 kArgumentsIdentifier, | 935 kArgumentsIdentifier, |
924 kUndefinedIdentifier, | 936 kUndefinedIdentifier, |
925 kPrototypeIdentifier, | 937 kPrototypeIdentifier, |
926 kConstructorIdentifier | 938 kConstructorIdentifier |
927 }; | 939 }; |
928 | 940 |
929 explicit PreParserIdentifier(Type type) : type_(type) {} | 941 explicit PreParserIdentifier(Type type) : type_(type) {} |
930 Type type_; | 942 Type type_; |
931 | 943 |
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 *message = MessageTemplate::kUnexpectedTokenIdentifier; | 2002 *message = MessageTemplate::kUnexpectedTokenIdentifier; |
1991 *arg = nullptr; | 2003 *arg = nullptr; |
1992 break; | 2004 break; |
1993 case Token::FUTURE_RESERVED_WORD: | 2005 case Token::FUTURE_RESERVED_WORD: |
1994 *message = MessageTemplate::kUnexpectedReserved; | 2006 *message = MessageTemplate::kUnexpectedReserved; |
1995 *arg = nullptr; | 2007 *arg = nullptr; |
1996 break; | 2008 break; |
1997 case Token::LET: | 2009 case Token::LET: |
1998 case Token::STATIC: | 2010 case Token::STATIC: |
1999 case Token::YIELD: | 2011 case Token::YIELD: |
| 2012 case Token::ASYNC: |
2000 case Token::FUTURE_STRICT_RESERVED_WORD: | 2013 case Token::FUTURE_STRICT_RESERVED_WORD: |
2001 *message = is_strict(language_mode()) | 2014 *message = is_strict(language_mode()) |
2002 ? MessageTemplate::kUnexpectedStrictReserved | 2015 ? MessageTemplate::kUnexpectedStrictReserved |
2003 : MessageTemplate::kUnexpectedTokenIdentifier; | 2016 : MessageTemplate::kUnexpectedTokenIdentifier; |
2004 *arg = nullptr; | 2017 *arg = nullptr; |
2005 break; | 2018 break; |
2006 case Token::TEMPLATE_SPAN: | 2019 case Token::TEMPLATE_SPAN: |
2007 case Token::TEMPLATE_TAIL: | 2020 case Token::TEMPLATE_TAIL: |
2008 *message = MessageTemplate::kUnexpectedTemplateString; | 2021 *message = MessageTemplate::kUnexpectedTemplateString; |
2009 *arg = nullptr; | 2022 *arg = nullptr; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2101 } | 2114 } |
2102 | 2115 |
2103 if (classifier->duplicate_finder() != nullptr && | 2116 if (classifier->duplicate_finder() != nullptr && |
2104 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { | 2117 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { |
2105 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | 2118 classifier->RecordDuplicateFormalParameterError(scanner()->location()); |
2106 } | 2119 } |
2107 return name; | 2120 return name; |
2108 } else if (is_sloppy(language_mode()) && | 2121 } else if (is_sloppy(language_mode()) && |
2109 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 2122 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
2110 next == Token::LET || next == Token::STATIC || | 2123 next == Token::LET || next == Token::STATIC || |
| 2124 next == Token::ASYNC || |
2111 (next == Token::YIELD && !is_generator()))) { | 2125 (next == Token::YIELD && !is_generator()))) { |
2112 classifier->RecordStrictModeFormalParameterError( | 2126 classifier->RecordStrictModeFormalParameterError( |
2113 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); | 2127 scanner()->location(), MessageTemplate::kUnexpectedStrictReserved); |
2114 if (next == Token::LET) { | 2128 if (next == Token::LET) { |
2115 classifier->RecordLetPatternError(scanner()->location(), | 2129 classifier->RecordLetPatternError(scanner()->location(), |
2116 MessageTemplate::kLetInLexicalBinding); | 2130 MessageTemplate::kLetInLexicalBinding); |
2117 } | 2131 } |
2118 return this->GetSymbol(scanner()); | 2132 return this->GetSymbol(scanner()); |
| 2133 } else if (next == Token::ASYNC) { |
| 2134 // Async token is special because it's allowed in any mode |
| 2135 // as identifier name |
| 2136 return this->GetSymbol(scanner()); |
2119 } else { | 2137 } else { |
2120 this->ReportUnexpectedToken(next); | 2138 this->ReportUnexpectedToken(next); |
2121 *ok = false; | 2139 *ok = false; |
2122 return Traits::EmptyIdentifier(); | 2140 return Traits::EmptyIdentifier(); |
2123 } | 2141 } |
2124 } | 2142 } |
2125 | 2143 |
2126 | 2144 |
2127 template <class Traits> | 2145 template <class Traits> |
2128 typename ParserBase<Traits>::IdentifierT ParserBase< | 2146 typename ParserBase<Traits>::IdentifierT ParserBase< |
2129 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, | 2147 Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved, |
2130 bool* ok) { | 2148 bool* ok) { |
2131 Token::Value next = Next(); | 2149 Token::Value next = Next(); |
2132 if (next == Token::IDENTIFIER) { | 2150 // Async is allowed as an identifier |
| 2151 if (next == Token::IDENTIFIER || next == Token::ASYNC) { |
2133 *is_strict_reserved = false; | 2152 *is_strict_reserved = false; |
2134 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || | 2153 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET || |
2135 next == Token::STATIC || | 2154 next == Token::STATIC || |
2136 (next == Token::YIELD && !this->is_generator())) { | 2155 (next == Token::YIELD && !this->is_generator())) { |
2137 *is_strict_reserved = true; | 2156 *is_strict_reserved = true; |
2138 } else { | 2157 } else { |
2139 ReportUnexpectedToken(next); | 2158 ReportUnexpectedToken(next); |
2140 *ok = false; | 2159 *ok = false; |
2141 return Traits::EmptyIdentifier(); | 2160 return Traits::EmptyIdentifier(); |
2142 } | 2161 } |
2143 | 2162 |
2144 IdentifierT name = this->GetSymbol(scanner()); | 2163 IdentifierT name = this->GetSymbol(scanner()); |
2145 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 2164 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
2146 return name; | 2165 return name; |
2147 } | 2166 } |
2148 | 2167 |
2149 | 2168 |
2150 template <class Traits> | 2169 template <class Traits> |
2151 typename ParserBase<Traits>::IdentifierT | 2170 typename ParserBase<Traits>::IdentifierT |
2152 ParserBase<Traits>::ParseIdentifierName(bool* ok) { | 2171 ParserBase<Traits>::ParseIdentifierName(bool* ok) { |
2153 Token::Value next = Next(); | 2172 Token::Value next = Next(); |
2154 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && | 2173 if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD && |
2155 next != Token::LET && next != Token::STATIC && next != Token::YIELD && | 2174 next != Token::LET && next != Token::STATIC && next != Token::YIELD && |
2156 next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) { | 2175 next != Token::ASYNC && next != Token::FUTURE_STRICT_RESERVED_WORD && |
| 2176 !Token::IsKeyword(next)) { |
2157 this->ReportUnexpectedToken(next); | 2177 this->ReportUnexpectedToken(next); |
2158 *ok = false; | 2178 *ok = false; |
2159 return Traits::EmptyIdentifier(); | 2179 return Traits::EmptyIdentifier(); |
2160 } | 2180 } |
2161 | 2181 |
2162 IdentifierT name = this->GetSymbol(scanner()); | 2182 IdentifierT name = this->GetSymbol(scanner()); |
2163 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); | 2183 if (this->IsArguments(name)) scope_->RecordArgumentsUsage(); |
2164 return name; | 2184 return name; |
2165 } | 2185 } |
2166 | 2186 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2273 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); | 2293 scanner()->peek_location(), MessageTemplate::kUnexpectedTokenNumber); |
2274 Next(); | 2294 Next(); |
2275 result = | 2295 result = |
2276 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); | 2296 this->ExpressionFromLiteral(token, beg_pos, scanner(), factory()); |
2277 break; | 2297 break; |
2278 | 2298 |
2279 case Token::IDENTIFIER: | 2299 case Token::IDENTIFIER: |
2280 case Token::LET: | 2300 case Token::LET: |
2281 case Token::STATIC: | 2301 case Token::STATIC: |
2282 case Token::YIELD: | 2302 case Token::YIELD: |
| 2303 case Token::ASYNC: |
2283 case Token::FUTURE_STRICT_RESERVED_WORD: { | 2304 case Token::FUTURE_STRICT_RESERVED_WORD: { |
2284 // Using eval or arguments in this context is OK even in strict mode. | 2305 // Using eval or arguments in this context is OK even in strict mode. |
2285 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); | 2306 IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK); |
2286 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, | 2307 result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_, |
2287 factory()); | 2308 factory()); |
2288 break; | 2309 break; |
2289 } | 2310 } |
2290 | 2311 |
2291 case Token::STRING: { | 2312 case Token::STRING: { |
2292 classifier->RecordBindingPatternError( | 2313 classifier->RecordBindingPatternError( |
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3441 // No 'new' or 'super' keyword. | 3462 // No 'new' or 'super' keyword. |
3442 return this->ParseMemberExpression(classifier, ok); | 3463 return this->ParseMemberExpression(classifier, ok); |
3443 } | 3464 } |
3444 | 3465 |
3445 | 3466 |
3446 template <class Traits> | 3467 template <class Traits> |
3447 typename ParserBase<Traits>::ExpressionT | 3468 typename ParserBase<Traits>::ExpressionT |
3448 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, | 3469 ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier, |
3449 bool* ok) { | 3470 bool* ok) { |
3450 // MemberExpression :: | 3471 // MemberExpression :: |
3451 // (PrimaryExpression | FunctionLiteral | ClassLiteral) | 3472 // (PrimaryExpression | FunctionLiteral | AsyncLiteral | ClassLiteral) |
3452 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* | 3473 // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)* |
3453 | 3474 |
3454 // The '[' Expression ']' and '.' Identifier parts are parsed by | 3475 // The '[' Expression ']' and '.' Identifier parts are parsed by |
3455 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | 3476 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
3456 // caller. | 3477 // caller. |
3457 | 3478 |
3458 // Parse the initial primary or function expression. | 3479 // Parse the initial primary or function expression. |
3459 ExpressionT result = this->EmptyExpression(); | 3480 ExpressionT result = this->EmptyExpression(); |
3460 if (peek() == Token::FUNCTION) { | 3481 Token::Value token = peek(); |
| 3482 if (token == Token::FUNCTION || |
| 3483 (allow_harmony_async_await() && token == Token::ASYNC && |
| 3484 IsNextAsyncFunctionKeyword())) { |
| 3485 bool is_async = Check(Token::ASYNC); |
3461 BindingPatternUnexpectedToken(classifier); | 3486 BindingPatternUnexpectedToken(classifier); |
3462 ArrowFormalParametersUnexpectedToken(classifier); | 3487 ArrowFormalParametersUnexpectedToken(classifier); |
3463 | 3488 |
3464 Consume(Token::FUNCTION); | 3489 Consume(Token::FUNCTION); |
3465 int function_token_position = position(); | 3490 int function_token_position = position(); |
3466 bool is_generator = Check(Token::MUL); | 3491 bool is_generator = is_async ? false : Check(Token::MUL); |
3467 IdentifierT name = this->EmptyIdentifier(); | 3492 IdentifierT name = this->EmptyIdentifier(); |
3468 bool is_strict_reserved_name = false; | 3493 bool is_strict_reserved_name = false; |
3469 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3494 Scanner::Location function_name_location = Scanner::Location::invalid(); |
3470 FunctionLiteral::FunctionType function_type = | 3495 FunctionLiteral::FunctionType function_type = |
3471 FunctionLiteral::ANONYMOUS_EXPRESSION; | 3496 FunctionLiteral::ANONYMOUS_EXPRESSION; |
3472 if (peek_any_identifier()) { | 3497 if (peek_any_identifier()) { |
3473 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3498 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
3474 CHECK_OK); | 3499 CHECK_OK); |
3475 function_name_location = scanner()->location(); | 3500 function_name_location = scanner()->location(); |
3476 function_type = FunctionLiteral::NAMED_EXPRESSION; | 3501 function_type = FunctionLiteral::NAMED_EXPRESSION; |
3477 } | 3502 } |
| 3503 |
| 3504 FunctionKind kind = FunctionKind::kNormalFunction; |
| 3505 if (is_generator) { |
| 3506 kind = FunctionKind::kGeneratorFunction; |
| 3507 } else if (is_async) { |
| 3508 kind = FunctionKind::kAsyncFunction; |
| 3509 } |
| 3510 |
3478 result = this->ParseFunctionLiteral( | 3511 result = this->ParseFunctionLiteral( |
3479 name, function_name_location, | 3512 name, function_name_location, |
3480 is_strict_reserved_name ? kFunctionNameIsStrictReserved | 3513 is_strict_reserved_name ? kFunctionNameIsStrictReserved |
3481 : kFunctionNameValidityUnknown, | 3514 : kFunctionNameValidityUnknown, |
3482 is_generator ? FunctionKind::kGeneratorFunction | 3515 kind, function_token_position, function_type, |
3483 : FunctionKind::kNormalFunction, | 3516 FunctionLiteral::NORMAL_ARITY, language_mode(), CHECK_OK); |
3484 function_token_position, function_type, FunctionLiteral::NORMAL_ARITY, | |
3485 language_mode(), CHECK_OK); | |
3486 } else if (peek() == Token::SUPER) { | 3517 } else if (peek() == Token::SUPER) { |
3487 const bool is_new = false; | 3518 const bool is_new = false; |
3488 result = ParseSuperExpression(is_new, classifier, CHECK_OK); | 3519 result = ParseSuperExpression(is_new, classifier, CHECK_OK); |
3489 } else { | 3520 } else { |
3490 result = ParsePrimaryExpression(classifier, CHECK_OK); | 3521 result = ParsePrimaryExpression(classifier, CHECK_OK); |
3491 } | 3522 } |
3492 | 3523 |
3493 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); | 3524 result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK); |
3494 return result; | 3525 return result; |
3495 } | 3526 } |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3893 return false; | 3924 return false; |
3894 } | 3925 } |
3895 Token::Value next_next = PeekAhead(); | 3926 Token::Value next_next = PeekAhead(); |
3896 switch (next_next) { | 3927 switch (next_next) { |
3897 case Token::LBRACE: | 3928 case Token::LBRACE: |
3898 case Token::LBRACK: | 3929 case Token::LBRACK: |
3899 case Token::IDENTIFIER: | 3930 case Token::IDENTIFIER: |
3900 case Token::STATIC: | 3931 case Token::STATIC: |
3901 case Token::LET: // Yes, you can do let let = ... in sloppy mode | 3932 case Token::LET: // Yes, you can do let let = ... in sloppy mode |
3902 case Token::YIELD: | 3933 case Token::YIELD: |
| 3934 case Token::ASYNC: |
3903 return true; | 3935 return true; |
3904 default: | 3936 default: |
3905 return false; | 3937 return false; |
3906 } | 3938 } |
3907 } | 3939 } |
3908 | 3940 |
3909 | 3941 |
3910 template <class Traits> | 3942 template <class Traits> |
| 3943 bool ParserBase<Traits>::IsNextAsyncFunctionKeyword() { |
| 3944 DCHECK(peek() == Token::ASYNC); |
| 3945 Token::Value next_next = PeekAhead(); |
| 3946 return next_next == Token::FUNCTION && |
| 3947 !scanner()->HasAnyLineTerminatorBeforeNext(); |
| 3948 } |
| 3949 |
| 3950 |
| 3951 template <class Traits> |
3911 typename ParserBase<Traits>::ExpressionT | 3952 typename ParserBase<Traits>::ExpressionT |
3912 ParserBase<Traits>::ParseArrowFunctionLiteral( | 3953 ParserBase<Traits>::ParseArrowFunctionLiteral( |
3913 bool accept_IN, const FormalParametersT& formal_parameters, | 3954 bool accept_IN, const FormalParametersT& formal_parameters, |
3914 const ExpressionClassifier& formals_classifier, bool* ok) { | 3955 const ExpressionClassifier& formals_classifier, bool* ok) { |
3915 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3956 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
3916 // ASI inserts `;` after arrow parameters if a line terminator is found. | 3957 // ASI inserts `;` after arrow parameters if a line terminator is found. |
3917 // `=> ...` is never a valid expression, so report as syntax error. | 3958 // `=> ...` is never a valid expression, so report as syntax error. |
3918 // If next token is not `=>`, it's a syntax error anyways. | 3959 // If next token is not `=>`, it's a syntax error anyways. |
3919 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 3960 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
3920 *ok = false; | 3961 *ok = false; |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4214 return; | 4255 return; |
4215 } | 4256 } |
4216 has_seen_constructor_ = true; | 4257 has_seen_constructor_ = true; |
4217 return; | 4258 return; |
4218 } | 4259 } |
4219 } | 4260 } |
4220 } // namespace internal | 4261 } // namespace internal |
4221 } // namespace v8 | 4262 } // namespace v8 |
4222 | 4263 |
4223 #endif // V8_PREPARSER_H | 4264 #endif // V8_PREPARSER_H |
OLD | NEW |