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