| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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_EXPRESSION_CLASSIFIER_H | 5 #ifndef V8_PARSING_EXPRESSION_CLASSIFIER_H |
| 6 #define V8_PARSING_EXPRESSION_CLASSIFIER_H | 6 #define V8_PARSING_EXPRESSION_CLASSIFIER_H |
| 7 | 7 |
| 8 #include "src/messages.h" | 8 #include "src/messages.h" |
| 9 #include "src/parsing/scanner.h" | 9 #include "src/parsing/scanner.h" |
| 10 #include "src/parsing/token.h" | 10 #include "src/parsing/token.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 | 14 |
| 15 | 15 |
| 16 template <typename Traits> | |
| 17 class ExpressionClassifier { | 16 class ExpressionClassifier { |
| 18 public: | 17 public: |
| 19 struct Error { | 18 struct Error { |
| 20 Error() | 19 Error() |
| 21 : location(Scanner::Location::invalid()), | 20 : location(Scanner::Location::invalid()), |
| 22 message(MessageTemplate::kNone), | 21 message(MessageTemplate::kNone), |
| 23 type(kSyntaxError), | 22 type(kSyntaxError), |
| 24 arg(nullptr) {} | 23 arg(nullptr) {} |
| 25 | 24 |
| 26 Scanner::Location location; | 25 Scanner::Location location; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 49 StrictModeFormalParametersProduction | | 48 StrictModeFormalParametersProduction | |
| 50 StrongModeFormalParametersProduction), | 49 StrongModeFormalParametersProduction), |
| 51 StandardProductions = ExpressionProductions | PatternProductions, | 50 StandardProductions = ExpressionProductions | PatternProductions, |
| 52 AllProductions = | 51 AllProductions = |
| 53 (StandardProductions | FormalParametersProductions | | 52 (StandardProductions | FormalParametersProductions | |
| 54 ArrowFormalParametersProduction | CoverInitializedNameProduction) | 53 ArrowFormalParametersProduction | CoverInitializedNameProduction) |
| 55 }; | 54 }; |
| 56 | 55 |
| 57 enum FunctionProperties { NonSimpleParameter = 1 << 0 }; | 56 enum FunctionProperties { NonSimpleParameter = 1 << 0 }; |
| 58 | 57 |
| 59 explicit ExpressionClassifier(const Traits* t) | 58 ExpressionClassifier() |
| 60 : zone_(t->zone()), | 59 : invalid_productions_(0), |
| 61 non_patterns_to_rewrite_(t->GetNonPatternList()), | |
| 62 invalid_productions_(0), | |
| 63 function_properties_(0), | 60 function_properties_(0), |
| 64 duplicate_finder_(nullptr) { | 61 duplicate_finder_(nullptr) {} |
| 65 non_pattern_begin_ = non_patterns_to_rewrite_->length(); | |
| 66 } | |
| 67 | 62 |
| 68 ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder) | 63 explicit ExpressionClassifier(DuplicateFinder* duplicate_finder) |
| 69 : zone_(t->zone()), | 64 : invalid_productions_(0), |
| 70 non_patterns_to_rewrite_(t->GetNonPatternList()), | |
| 71 invalid_productions_(0), | |
| 72 function_properties_(0), | 65 function_properties_(0), |
| 73 duplicate_finder_(duplicate_finder) { | 66 duplicate_finder_(duplicate_finder) {} |
| 74 non_pattern_begin_ = non_patterns_to_rewrite_->length(); | |
| 75 } | |
| 76 | |
| 77 ~ExpressionClassifier() { Discard(); } | |
| 78 | 67 |
| 79 bool is_valid(unsigned productions) const { | 68 bool is_valid(unsigned productions) const { |
| 80 return (invalid_productions_ & productions) == 0; | 69 return (invalid_productions_ & productions) == 0; |
| 81 } | 70 } |
| 82 | 71 |
| 83 DuplicateFinder* duplicate_finder() const { return duplicate_finder_; } | 72 DuplicateFinder* duplicate_finder() const { return duplicate_finder_; } |
| 84 | 73 |
| 85 bool is_valid_expression() const { return is_valid(ExpressionProduction); } | 74 bool is_valid_expression() const { return is_valid(ExpressionProduction); } |
| 86 | 75 |
| 87 bool is_valid_formal_parameter_initializer() const { | 76 bool is_valid_formal_parameter_initializer() const { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 void ForgiveCoverInitializedNameError() { | 274 void ForgiveCoverInitializedNameError() { |
| 286 invalid_productions_ &= ~CoverInitializedNameProduction; | 275 invalid_productions_ &= ~CoverInitializedNameProduction; |
| 287 cover_initialized_name_error_ = Error(); | 276 cover_initialized_name_error_ = Error(); |
| 288 } | 277 } |
| 289 | 278 |
| 290 void ForgiveAssignmentPatternError() { | 279 void ForgiveAssignmentPatternError() { |
| 291 invalid_productions_ &= ~AssignmentPatternProduction; | 280 invalid_productions_ &= ~AssignmentPatternProduction; |
| 292 assignment_pattern_error_ = Error(); | 281 assignment_pattern_error_ = Error(); |
| 293 } | 282 } |
| 294 | 283 |
| 295 void Accumulate(ExpressionClassifier* inner, | 284 void Accumulate(const ExpressionClassifier& inner, |
| 296 unsigned productions = StandardProductions, | 285 unsigned productions = StandardProductions) { |
| 297 bool merge_non_patterns = true) { | |
| 298 if (merge_non_patterns) MergeNonPatterns(inner); | |
| 299 // Propagate errors from inner, but don't overwrite already recorded | 286 // Propagate errors from inner, but don't overwrite already recorded |
| 300 // errors. | 287 // errors. |
| 301 unsigned non_arrow_inner_invalid_productions = | 288 unsigned non_arrow_inner_invalid_productions = |
| 302 inner->invalid_productions_ & ~ArrowFormalParametersProduction; | 289 inner.invalid_productions_ & ~ArrowFormalParametersProduction; |
| 303 if (non_arrow_inner_invalid_productions == 0) return; | 290 if (non_arrow_inner_invalid_productions == 0) return; |
| 304 unsigned non_arrow_productions = | 291 unsigned non_arrow_productions = |
| 305 productions & ~ArrowFormalParametersProduction; | 292 productions & ~ArrowFormalParametersProduction; |
| 306 unsigned errors = | 293 unsigned errors = |
| 307 non_arrow_productions & non_arrow_inner_invalid_productions; | 294 non_arrow_productions & non_arrow_inner_invalid_productions; |
| 308 errors &= ~invalid_productions_; | 295 errors &= ~invalid_productions_; |
| 309 if (errors != 0) { | 296 if (errors != 0) { |
| 310 invalid_productions_ |= errors; | 297 invalid_productions_ |= errors; |
| 311 if (errors & ExpressionProduction) | 298 if (errors & ExpressionProduction) |
| 312 expression_error_ = inner->expression_error_; | 299 expression_error_ = inner.expression_error_; |
| 313 if (errors & FormalParameterInitializerProduction) | 300 if (errors & FormalParameterInitializerProduction) |
| 314 formal_parameter_initializer_error_ = | 301 formal_parameter_initializer_error_ = |
| 315 inner->formal_parameter_initializer_error_; | 302 inner.formal_parameter_initializer_error_; |
| 316 if (errors & BindingPatternProduction) | 303 if (errors & BindingPatternProduction) |
| 317 binding_pattern_error_ = inner->binding_pattern_error_; | 304 binding_pattern_error_ = inner.binding_pattern_error_; |
| 318 if (errors & AssignmentPatternProduction) | 305 if (errors & AssignmentPatternProduction) |
| 319 assignment_pattern_error_ = inner->assignment_pattern_error_; | 306 assignment_pattern_error_ = inner.assignment_pattern_error_; |
| 320 if (errors & DistinctFormalParametersProduction) | 307 if (errors & DistinctFormalParametersProduction) |
| 321 duplicate_formal_parameter_error_ = | 308 duplicate_formal_parameter_error_ = |
| 322 inner->duplicate_formal_parameter_error_; | 309 inner.duplicate_formal_parameter_error_; |
| 323 if (errors & StrictModeFormalParametersProduction) | 310 if (errors & StrictModeFormalParametersProduction) |
| 324 strict_mode_formal_parameter_error_ = | 311 strict_mode_formal_parameter_error_ = |
| 325 inner->strict_mode_formal_parameter_error_; | 312 inner.strict_mode_formal_parameter_error_; |
| 326 if (errors & StrongModeFormalParametersProduction) | 313 if (errors & StrongModeFormalParametersProduction) |
| 327 strong_mode_formal_parameter_error_ = | 314 strong_mode_formal_parameter_error_ = |
| 328 inner->strong_mode_formal_parameter_error_; | 315 inner.strong_mode_formal_parameter_error_; |
| 329 if (errors & LetPatternProduction) | 316 if (errors & LetPatternProduction) |
| 330 let_pattern_error_ = inner->let_pattern_error_; | 317 let_pattern_error_ = inner.let_pattern_error_; |
| 331 if (errors & CoverInitializedNameProduction) | 318 if (errors & CoverInitializedNameProduction) |
| 332 cover_initialized_name_error_ = inner->cover_initialized_name_error_; | 319 cover_initialized_name_error_ = inner.cover_initialized_name_error_; |
| 333 } | 320 } |
| 334 | 321 |
| 335 // As an exception to the above, the result continues to be a valid arrow | 322 // As an exception to the above, the result continues to be a valid arrow |
| 336 // formal parameters if the inner expression is a valid binding pattern. | 323 // formal parameters if the inner expression is a valid binding pattern. |
| 337 if (productions & ArrowFormalParametersProduction && | 324 if (productions & ArrowFormalParametersProduction && |
| 338 is_valid_arrow_formal_parameters()) { | 325 is_valid_arrow_formal_parameters()) { |
| 339 // Also copy function properties if expecting an arrow function | 326 // Also copy function properties if expecting an arrow function |
| 340 // parameter. | 327 // parameter. |
| 341 function_properties_ |= inner->function_properties_; | 328 function_properties_ |= inner.function_properties_; |
| 342 | 329 |
| 343 if (!inner->is_valid_binding_pattern()) { | 330 if (!inner.is_valid_binding_pattern()) { |
| 344 invalid_productions_ |= ArrowFormalParametersProduction; | 331 invalid_productions_ |= ArrowFormalParametersProduction; |
| 345 arrow_formal_parameters_error_ = inner->binding_pattern_error_; | 332 arrow_formal_parameters_error_ = inner.binding_pattern_error_; |
| 346 } | 333 } |
| 347 } | 334 } |
| 348 } | 335 } |
| 349 | 336 |
| 350 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } | |
| 351 | |
| 352 V8_INLINE void Discard() { | |
| 353 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length()); | |
| 354 non_patterns_to_rewrite_->Rewind(non_pattern_begin_); | |
| 355 } | |
| 356 | |
| 357 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) { | |
| 358 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_); | |
| 359 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length(); | |
| 360 } | |
| 361 | |
| 362 private: | 337 private: |
| 363 Zone* zone_; | |
| 364 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; | |
| 365 int non_pattern_begin_; | |
| 366 unsigned invalid_productions_; | 338 unsigned invalid_productions_; |
| 367 unsigned function_properties_; | 339 unsigned function_properties_; |
| 368 Error expression_error_; | 340 Error expression_error_; |
| 369 Error formal_parameter_initializer_error_; | 341 Error formal_parameter_initializer_error_; |
| 370 Error binding_pattern_error_; | 342 Error binding_pattern_error_; |
| 371 Error assignment_pattern_error_; | 343 Error assignment_pattern_error_; |
| 372 Error arrow_formal_parameters_error_; | 344 Error arrow_formal_parameters_error_; |
| 373 Error duplicate_formal_parameter_error_; | 345 Error duplicate_formal_parameter_error_; |
| 374 Error strict_mode_formal_parameter_error_; | 346 Error strict_mode_formal_parameter_error_; |
| 375 Error strong_mode_formal_parameter_error_; | 347 Error strong_mode_formal_parameter_error_; |
| 376 Error let_pattern_error_; | 348 Error let_pattern_error_; |
| 377 Error cover_initialized_name_error_; | 349 Error cover_initialized_name_error_; |
| 378 DuplicateFinder* duplicate_finder_; | 350 DuplicateFinder* duplicate_finder_; |
| 379 }; | 351 }; |
| 380 | 352 |
| 381 | |
| 382 } // namespace internal | 353 } // namespace internal |
| 383 } // namespace v8 | 354 } // namespace v8 |
| 384 | 355 |
| 385 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H | 356 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H |
| OLD | NEW |