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 |