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

Side by Side Diff: src/preparser.h

Issue 1423663006: [es7] Implement async functions parsing Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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
« no previous file with comments | « src/parser.cc ('k') | src/preparser.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 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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698