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 |