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_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 stack_overflow_(false), | 192 stack_overflow_(false), |
193 allow_lazy_(false), | 193 allow_lazy_(false), |
194 allow_natives_(false), | 194 allow_natives_(false), |
195 allow_tailcalls_(false), | 195 allow_tailcalls_(false), |
196 allow_harmony_restrictive_declarations_(false), | 196 allow_harmony_restrictive_declarations_(false), |
197 allow_harmony_do_expressions_(false), | 197 allow_harmony_do_expressions_(false), |
198 allow_harmony_for_in_(false), | 198 allow_harmony_for_in_(false), |
199 allow_harmony_function_name_(false), | 199 allow_harmony_function_name_(false), |
200 allow_harmony_function_sent_(false), | 200 allow_harmony_function_sent_(false), |
201 allow_harmony_async_await_(false), | 201 allow_harmony_async_await_(false), |
202 allow_harmony_restrictive_generators_(false) {} | 202 allow_harmony_restrictive_generators_(false), |
203 allow_harmony_trailing_commas_in_parameters_(false) {} | |
203 | 204 |
204 #define ALLOW_ACCESSORS(name) \ | 205 #define ALLOW_ACCESSORS(name) \ |
205 bool allow_##name() const { return allow_##name##_; } \ | 206 bool allow_##name() const { return allow_##name##_; } \ |
206 void set_allow_##name(bool allow) { allow_##name##_ = allow; } | 207 void set_allow_##name(bool allow) { allow_##name##_ = allow; } |
207 | 208 |
208 #define SCANNER_ACCESSORS(name) \ | 209 #define SCANNER_ACCESSORS(name) \ |
209 bool allow_##name() const { return scanner_->allow_##name(); } \ | 210 bool allow_##name() const { return scanner_->allow_##name(); } \ |
210 void set_allow_##name(bool allow) { \ | 211 void set_allow_##name(bool allow) { \ |
211 return scanner_->set_allow_##name(allow); \ | 212 return scanner_->set_allow_##name(allow); \ |
212 } | 213 } |
213 | 214 |
214 ALLOW_ACCESSORS(lazy); | 215 ALLOW_ACCESSORS(lazy); |
215 ALLOW_ACCESSORS(natives); | 216 ALLOW_ACCESSORS(natives); |
216 ALLOW_ACCESSORS(tailcalls); | 217 ALLOW_ACCESSORS(tailcalls); |
217 ALLOW_ACCESSORS(harmony_restrictive_declarations); | 218 ALLOW_ACCESSORS(harmony_restrictive_declarations); |
218 ALLOW_ACCESSORS(harmony_do_expressions); | 219 ALLOW_ACCESSORS(harmony_do_expressions); |
219 ALLOW_ACCESSORS(harmony_for_in); | 220 ALLOW_ACCESSORS(harmony_for_in); |
220 ALLOW_ACCESSORS(harmony_function_name); | 221 ALLOW_ACCESSORS(harmony_function_name); |
221 ALLOW_ACCESSORS(harmony_function_sent); | 222 ALLOW_ACCESSORS(harmony_function_sent); |
222 ALLOW_ACCESSORS(harmony_async_await); | 223 ALLOW_ACCESSORS(harmony_async_await); |
223 ALLOW_ACCESSORS(harmony_restrictive_generators); | 224 ALLOW_ACCESSORS(harmony_restrictive_generators); |
225 ALLOW_ACCESSORS(harmony_trailing_commas_in_parameters); | |
224 SCANNER_ACCESSORS(harmony_exponentiation_operator); | 226 SCANNER_ACCESSORS(harmony_exponentiation_operator); |
225 | 227 |
226 #undef SCANNER_ACCESSORS | 228 #undef SCANNER_ACCESSORS |
227 #undef ALLOW_ACCESSORS | 229 #undef ALLOW_ACCESSORS |
228 | 230 |
229 uintptr_t stack_limit() const { return stack_limit_; } | 231 uintptr_t stack_limit() const { return stack_limit_; } |
230 | 232 |
231 protected: | 233 protected: |
232 enum AllowRestrictedIdentifiers { | 234 enum AllowRestrictedIdentifiers { |
233 kAllowRestrictedIdentifiers, | 235 kAllowRestrictedIdentifiers, |
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1185 bool allow_lazy_; | 1187 bool allow_lazy_; |
1186 bool allow_natives_; | 1188 bool allow_natives_; |
1187 bool allow_tailcalls_; | 1189 bool allow_tailcalls_; |
1188 bool allow_harmony_restrictive_declarations_; | 1190 bool allow_harmony_restrictive_declarations_; |
1189 bool allow_harmony_do_expressions_; | 1191 bool allow_harmony_do_expressions_; |
1190 bool allow_harmony_for_in_; | 1192 bool allow_harmony_for_in_; |
1191 bool allow_harmony_function_name_; | 1193 bool allow_harmony_function_name_; |
1192 bool allow_harmony_function_sent_; | 1194 bool allow_harmony_function_sent_; |
1193 bool allow_harmony_async_await_; | 1195 bool allow_harmony_async_await_; |
1194 bool allow_harmony_restrictive_generators_; | 1196 bool allow_harmony_restrictive_generators_; |
1197 bool allow_harmony_trailing_commas_in_parameters_; | |
1195 }; | 1198 }; |
1196 | 1199 |
1197 template <class Traits> | 1200 template <class Traits> |
1198 ParserBase<Traits>::FunctionState::FunctionState( | 1201 ParserBase<Traits>::FunctionState::FunctionState( |
1199 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, | 1202 FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
1200 FunctionKind kind, typename Traits::Type::Factory* factory) | 1203 FunctionKind kind, typename Traits::Type::Factory* factory) |
1201 : next_materialized_literal_index_(0), | 1204 : next_materialized_literal_index_(0), |
1202 expected_property_count_(0), | 1205 expected_property_count_(0), |
1203 this_location_(Scanner::Location::invalid()), | 1206 this_location_(Scanner::Location::invalid()), |
1204 return_location_(Scanner::Location::invalid()), | 1207 return_location_(Scanner::Location::invalid()), |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1671 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); | 1674 ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); |
1672 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 1675 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
1673 return result; | 1676 return result; |
1674 } | 1677 } |
1675 | 1678 |
1676 template <class Traits> | 1679 template <class Traits> |
1677 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1680 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1678 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { | 1681 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { |
1679 // Expression :: | 1682 // Expression :: |
1680 // AssignmentExpression | 1683 // AssignmentExpression |
1681 // Expression ',' AssignmentExpression | 1684 // Expression ',' AssignmentExpression |
jwolfe
2016/06/22 18:04:41
If I'm supposed to update the grammar comments, I
caitp (gmail)
2016/06/22 18:56:20
The grammar that needs changing here is CoverParen
| |
1682 | 1685 |
1683 ExpressionT result = this->EmptyExpression(); | 1686 ExpressionT result = this->EmptyExpression(); |
1684 { | 1687 { |
1685 ExpressionClassifier binding_classifier(this); | 1688 ExpressionClassifier binding_classifier(this); |
1686 result = this->ParseAssignmentExpression(accept_IN, &binding_classifier, | 1689 result = this->ParseAssignmentExpression(accept_IN, &binding_classifier, |
1687 CHECK_OK); | 1690 CHECK_OK); |
1688 classifier->Accumulate(&binding_classifier, | 1691 classifier->Accumulate(&binding_classifier, |
1689 ExpressionClassifier::AllProductions); | 1692 ExpressionClassifier::AllProductions); |
1690 } | 1693 } |
1691 bool is_simple_parameter_list = this->IsIdentifier(result); | 1694 bool is_simple_parameter_list = this->IsIdentifier(result); |
1692 bool seen_rest = false; | 1695 bool seen_rest = false; |
1693 while (peek() == Token::COMMA) { | 1696 while (peek() == Token::COMMA) { |
1694 CheckNoTailCallExpressions(classifier, CHECK_OK); | 1697 CheckNoTailCallExpressions(classifier, CHECK_OK); |
1695 if (seen_rest) { | 1698 if (seen_rest) { |
1696 // At this point the production can't possibly be valid, but we don't know | 1699 // At this point the production can't possibly be valid, but we don't know |
1697 // which error to signal. | 1700 // which error to signal. |
1698 classifier->RecordArrowFormalParametersError( | 1701 classifier->RecordArrowFormalParametersError( |
1699 scanner()->peek_location(), MessageTemplate::kParamAfterRest); | 1702 scanner()->peek_location(), MessageTemplate::kParamAfterRest); |
1700 } | 1703 } |
1701 Consume(Token::COMMA); | 1704 Consume(Token::COMMA); |
1702 bool is_rest = false; | 1705 bool is_rest = false; |
1703 if (peek() == Token::ELLIPSIS) { | 1706 if (allow_harmony_trailing_commas_in_parameters() && |
1707 peek() == Token::RPAREN && PeekAhead() == Token::ARROW) { | |
1708 // a trailing comma is allowed at the end of an arrow parameter list | |
caitp (gmail)
2016/06/22 18:56:20
Is this approach using PeekAhead() faster than jus
adamk
2016/06/28 00:39:47
I have the same question :)
I'll be sad if this s
| |
1709 break; | |
1710 } else if (peek() == Token::ELLIPSIS) { | |
1704 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only | 1711 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only |
1705 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a | 1712 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a |
1706 // valid expression or binding pattern. | 1713 // valid expression or binding pattern. |
1707 ExpressionUnexpectedToken(classifier); | 1714 ExpressionUnexpectedToken(classifier); |
1708 BindingPatternUnexpectedToken(classifier); | 1715 BindingPatternUnexpectedToken(classifier); |
1709 Consume(Token::ELLIPSIS); | 1716 Consume(Token::ELLIPSIS); |
1710 seen_rest = is_rest = true; | 1717 seen_rest = is_rest = true; |
1711 } | 1718 } |
1712 int pos = position(), expr_pos = peek_position(); | 1719 int pos = position(), expr_pos = peek_position(); |
1713 ExpressionClassifier binding_classifier(this); | 1720 ExpressionClassifier binding_classifier(this); |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2140 literal_index, | 2147 literal_index, |
2141 number_of_boilerplate_properties, | 2148 number_of_boilerplate_properties, |
2142 pos); | 2149 pos); |
2143 } | 2150 } |
2144 | 2151 |
2145 template <class Traits> | 2152 template <class Traits> |
2146 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2153 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
2147 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, | 2154 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, |
2148 ExpressionClassifier* classifier, bool* ok) { | 2155 ExpressionClassifier* classifier, bool* ok) { |
2149 // Arguments :: | 2156 // Arguments :: |
2150 // '(' (AssignmentExpression)*[','] ')' | 2157 // '(' (AssignmentExpression)*[','] ')' |
jwolfe
2016/06/22 18:04:41
Does this comment say that a trailing comma is alr
caitp (gmail)
2016/06/22 18:56:20
I think this is just wrong, this doesn't even make
| |
2151 | 2158 |
2152 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2159 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2153 typename Traits::Type::ExpressionList result = | 2160 typename Traits::Type::ExpressionList result = |
2154 this->NewExpressionList(4, zone_); | 2161 this->NewExpressionList(4, zone_); |
2155 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2162 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2156 bool done = (peek() == Token::RPAREN); | 2163 bool done = (peek() == Token::RPAREN); |
2157 bool was_unspread = false; | 2164 bool was_unspread = false; |
2158 int unspread_sequences_count = 0; | 2165 int unspread_sequences_count = 0; |
2159 while (!done) { | 2166 while (!done) { |
2160 int start_pos = peek_position(); | 2167 int start_pos = peek_position(); |
(...skipping 23 matching lines...) Expand all Loading... | |
2184 } | 2191 } |
2185 | 2192 |
2186 if (result->length() > Code::kMaxArguments) { | 2193 if (result->length() > Code::kMaxArguments) { |
2187 ReportMessage(MessageTemplate::kTooManyArguments); | 2194 ReportMessage(MessageTemplate::kTooManyArguments); |
2188 *ok = false; | 2195 *ok = false; |
2189 return this->NullExpressionList(); | 2196 return this->NullExpressionList(); |
2190 } | 2197 } |
2191 done = (peek() != Token::COMMA); | 2198 done = (peek() != Token::COMMA); |
2192 if (!done) { | 2199 if (!done) { |
2193 Next(); | 2200 Next(); |
2201 if (allow_harmony_trailing_commas_in_parameters() && | |
2202 peek() == Token::RPAREN) { | |
2203 // allow trailing comma | |
2204 done = true; | |
2205 } | |
2194 } | 2206 } |
2195 } | 2207 } |
2196 Scanner::Location location = scanner_->location(); | 2208 Scanner::Location location = scanner_->location(); |
2197 if (Token::RPAREN != Next()) { | 2209 if (Token::RPAREN != Next()) { |
2198 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2210 ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
2199 *ok = false; | 2211 *ok = false; |
2200 return this->NullExpressionList(); | 2212 return this->NullExpressionList(); |
2201 } | 2213 } |
2202 *first_spread_arg_loc = spread_arg; | 2214 *first_spread_arg_loc = spread_arg; |
2203 | 2215 |
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3200 // FormalParameterList[?Yield, ?GeneratorParameter] | 3212 // FormalParameterList[?Yield, ?GeneratorParameter] |
3201 // | 3213 // |
3202 // FormalParameterList[Yield,GeneratorParameter] : | 3214 // FormalParameterList[Yield,GeneratorParameter] : |
3203 // FunctionRestParameter[?Yield] | 3215 // FunctionRestParameter[?Yield] |
3204 // FormalsList[?Yield, ?GeneratorParameter] | 3216 // FormalsList[?Yield, ?GeneratorParameter] |
3205 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] | 3217 // FormalsList[?Yield, ?GeneratorParameter] , FunctionRestParameter[?Yield] |
3206 // | 3218 // |
3207 // FormalsList[Yield,GeneratorParameter] : | 3219 // FormalsList[Yield,GeneratorParameter] : |
3208 // FormalParameter[?Yield, ?GeneratorParameter] | 3220 // FormalParameter[?Yield, ?GeneratorParameter] |
3209 // FormalsList[?Yield, ?GeneratorParameter] , | 3221 // FormalsList[?Yield, ?GeneratorParameter] , |
3210 // FormalParameter[?Yield,?GeneratorParameter] | 3222 // FormalParameter[?Yield,?GeneratorParameter] |
jwolfe
2016/06/22 18:04:41
Should I update this comment to the new grammar? R
caitp (gmail)
2016/06/22 18:56:20
Honestly I'd prefer the jeffmo proposal just refac
| |
3211 | 3223 |
3212 DCHECK_EQ(0, parameters->Arity()); | 3224 DCHECK_EQ(0, parameters->Arity()); |
3213 | 3225 |
3214 if (peek() != Token::RPAREN) { | 3226 if (peek() != Token::RPAREN) { |
3215 do { | 3227 while (true) { |
3216 if (parameters->Arity() > Code::kMaxArguments) { | 3228 if (parameters->Arity() > Code::kMaxArguments) { |
3217 ReportMessage(MessageTemplate::kTooManyParameters); | 3229 ReportMessage(MessageTemplate::kTooManyParameters); |
3218 *ok = false; | 3230 *ok = false; |
3219 return; | 3231 return; |
3220 } | 3232 } |
3221 parameters->has_rest = Check(Token::ELLIPSIS); | 3233 parameters->has_rest = Check(Token::ELLIPSIS); |
3222 ParseFormalParameter(parameters, classifier, ok); | 3234 ParseFormalParameter(parameters, classifier, ok); |
3223 if (!*ok) return; | 3235 if (!*ok) return; |
3224 } while (!parameters->has_rest && Check(Token::COMMA)); | |
3225 | 3236 |
3226 if (parameters->has_rest) { | 3237 if (parameters->has_rest) { |
3227 parameters->is_simple = false; | 3238 parameters->is_simple = false; |
3228 classifier->RecordNonSimpleParameter(); | 3239 classifier->RecordNonSimpleParameter(); |
3229 if (peek() == Token::COMMA) { | 3240 if (peek() == Token::COMMA) { |
3230 ReportMessageAt(scanner()->peek_location(), | 3241 ReportMessageAt(scanner()->peek_location(), |
3231 MessageTemplate::kParamAfterRest); | 3242 MessageTemplate::kParamAfterRest); |
3232 *ok = false; | 3243 *ok = false; |
3233 return; | 3244 return; |
3245 } | |
3246 break; | |
3247 } | |
3248 if (!Check(Token::COMMA)) break; | |
3249 if (allow_harmony_trailing_commas_in_parameters() && | |
caitp (gmail)
2016/06/22 18:56:20
For a lot of these, I feel like a WebKit-ism of de
| |
3250 peek() == Token::RPAREN) { | |
3251 // allow the trailing comma | |
3252 break; | |
3234 } | 3253 } |
3235 } | 3254 } |
3236 } | 3255 } |
3237 | 3256 |
3238 for (int i = 0; i < parameters->Arity(); ++i) { | 3257 for (int i = 0; i < parameters->Arity(); ++i) { |
3239 auto parameter = parameters->at(i); | 3258 auto parameter = parameters->at(i); |
3240 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); | 3259 Traits::DeclareFormalParameter(parameters->scope, parameter, classifier); |
3241 } | 3260 } |
3242 } | 3261 } |
3243 | 3262 |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3627 has_seen_constructor_ = true; | 3646 has_seen_constructor_ = true; |
3628 return; | 3647 return; |
3629 } | 3648 } |
3630 } | 3649 } |
3631 | 3650 |
3632 | 3651 |
3633 } // namespace internal | 3652 } // namespace internal |
3634 } // namespace v8 | 3653 } // namespace v8 |
3635 | 3654 |
3636 #endif // V8_PARSING_PARSER_BASE_H | 3655 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |