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" |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 Error& e = reported_error(kAssignmentPatternProduction); | 364 Error& e = reported_error(kAssignmentPatternProduction); |
365 e.kind = kUnusedError; | 365 e.kind = kUnusedError; |
366 } | 366 } |
367 | 367 |
368 void Accumulate(ExpressionClassifier* inner, | 368 void Accumulate(ExpressionClassifier* inner, |
369 unsigned productions = StandardProductions, | 369 unsigned productions = StandardProductions, |
370 bool merge_non_patterns = true) { | 370 bool merge_non_patterns = true) { |
371 DCHECK_EQ(inner->reported_errors_, reported_errors_); | 371 DCHECK_EQ(inner->reported_errors_, reported_errors_); |
372 DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_); | 372 DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_); |
373 DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length()); | 373 DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length()); |
| 374 |
374 if (merge_non_patterns) MergeNonPatterns(inner); | 375 if (merge_non_patterns) MergeNonPatterns(inner); |
375 // Propagate errors from inner, but don't overwrite already recorded | |
376 // errors. | |
377 unsigned non_arrow_inner_invalid_productions = | |
378 inner->invalid_productions_ & ~ArrowFormalParametersProduction; | |
379 if (non_arrow_inner_invalid_productions) { | |
380 unsigned errors = non_arrow_inner_invalid_productions & productions & | |
381 ~invalid_productions_; | |
382 // As an exception to the above, the result continues to be a valid arrow | |
383 // formal parameters if the inner expression is a valid binding pattern. | |
384 if (productions & ArrowFormalParametersProduction && | |
385 is_valid_arrow_formal_parameters()) { | |
386 // Also copy function properties if expecting an arrow function | |
387 // parameter. | |
388 function_properties_ |= inner->function_properties_; | |
389 | 376 |
390 if (!inner->is_valid_binding_pattern()) | 377 // Propagate errors from inner, excluding arrow formal parameters. |
391 errors |= ArrowFormalParametersProduction; | 378 unsigned errors = inner->invalid_productions_ & productions & |
392 } | 379 ~ArrowFormalParametersProduction; |
| 380 bool keep_inner = errors & ~invalid_productions_; |
| 381 bool copy_arrow = false; |
393 | 382 |
394 if (errors != 0) { | 383 // If there's nothing to add, the inner classifier's array can be dropped. |
395 invalid_productions_ |= errors; | 384 if (keep_inner) invalid_productions_ |= errors; |
396 int arrow_index = inner->reported_errors_end_; | 385 |
397 for (int i = inner->reported_errors_begin_; | 386 // As an exception to error propagation, the result continues to be valid |
398 i < inner->reported_errors_end_; i++) { | 387 // as arrow formal parameters if the inner expression is a valid binding |
399 if (reported_errors_->at(i).kind == kUnusedError || | 388 // pattern. |
400 reported_errors_->at(i).kind == kArrowFormalParametersProduction) | 389 if (productions & ArrowFormalParametersProduction && |
401 continue; | 390 is_valid_arrow_formal_parameters()) { |
402 if (errors & (1 << reported_errors_->at(i).kind)) | 391 // Also copy function properties if expecting an arrow function |
403 Move(i); | 392 // parameter. |
404 if (reported_errors_->at(i).kind == kBindingPatternProduction && | 393 function_properties_ |= inner->function_properties_; |
405 errors & ArrowFormalParametersProduction) { | 394 if (!inner->is_valid_binding_pattern()) { |
406 if (reported_errors_end_ <= i) { | 395 keep_inner = copy_arrow = true; |
407 Move(i); | 396 invalid_productions_ |= ArrowFormalParametersProduction; |
408 reported_errors_->at(reported_errors_end_-1).kind = | |
409 kArrowFormalParametersProduction; | |
410 } else { | |
411 DCHECK_EQ(reported_errors_end_, i+1); | |
412 arrow_index = i; | |
413 } | |
414 } | |
415 } | |
416 if (arrow_index < inner->reported_errors_end_) { | |
417 if (reported_errors_end_ < inner->reported_errors_end_) { | |
418 Replace(reported_errors_end_, arrow_index); | |
419 reported_errors_->at(reported_errors_end_++).kind = | |
420 kArrowFormalParametersProduction; | |
421 } else { | |
422 Add(reported_errors_->at(arrow_index)); | |
423 reported_errors_->at(reported_errors_end_-1).kind = | |
424 kArrowFormalParametersProduction; | |
425 } | |
426 } | |
427 } | 397 } |
428 } | 398 } |
429 reported_errors_->Rewind(reported_errors_end_); | 399 |
| 400 if (keep_inner) { |
| 401 reported_errors_end_ = inner->reported_errors_end_; |
| 402 if (copy_arrow) { |
| 403 Add(inner->reported_error(kBindingPatternProduction)); |
| 404 reported_errors_->at(reported_errors_end_-1).kind = |
| 405 kArrowFormalParametersProduction; |
| 406 } |
| 407 } else { |
| 408 reported_errors_->Rewind(reported_errors_end_); |
| 409 } |
| 410 |
430 inner->reported_errors_begin_ = inner->reported_errors_end_ = | 411 inner->reported_errors_begin_ = inner->reported_errors_end_ = |
431 reported_errors_end_; | 412 reported_errors_end_; |
432 } | 413 } |
433 | 414 |
434 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } | 415 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } |
435 | 416 |
436 V8_INLINE void Discard() { | 417 V8_INLINE void Discard() { |
437 if (reported_errors_end_ == reported_errors_->length()) { | 418 if (reported_errors_end_ == reported_errors_->length()) { |
438 reported_errors_->Rewind(reported_errors_begin_); | 419 reported_errors_->Rewind(reported_errors_begin_); |
439 reported_errors_end_ = reported_errors_begin_; | 420 reported_errors_end_ = reported_errors_begin_; |
(...skipping 22 matching lines...) Expand all Loading... |
462 static Error none; | 443 static Error none; |
463 return none; | 444 return none; |
464 } | 445 } |
465 | 446 |
466 V8_INLINE void Add(const Error& e) { | 447 V8_INLINE void Add(const Error& e) { |
467 DCHECK_EQ(reported_errors_end_, reported_errors_->length()); | 448 DCHECK_EQ(reported_errors_end_, reported_errors_->length()); |
468 reported_errors_->Add(e, zone_); | 449 reported_errors_->Add(e, zone_); |
469 reported_errors_end_++; | 450 reported_errors_end_++; |
470 } | 451 } |
471 | 452 |
472 V8_INLINE void Move(int i) { | |
473 DCHECK_LE(reported_errors_end_, i); | |
474 DCHECK_LT(i, reported_errors_->length()); | |
475 if (reported_errors_end_ < i) | |
476 reported_errors_->at(reported_errors_end_) = reported_errors_->at(i); | |
477 reported_errors_end_++; | |
478 } | |
479 | |
480 V8_INLINE void Replace(int j, int i) { | |
481 DCHECK_LT(i, reported_errors_->length()); | |
482 DCHECK_LE(j, reported_errors_end_); | |
483 DCHECK(j == reported_errors_end_ || | |
484 reported_errors_->at(j).kind == kUnusedError); | |
485 if (i != j) reported_errors_->at(j) = reported_errors_->at(i); | |
486 } | |
487 | |
488 Zone* zone_; | 453 Zone* zone_; |
489 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; | 454 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; |
490 int non_pattern_begin_; | 455 int non_pattern_begin_; |
491 unsigned invalid_productions_ : 14; | 456 unsigned invalid_productions_ : 14; |
492 unsigned function_properties_ : 2; | 457 unsigned function_properties_ : 2; |
493 ZoneList<Error>* reported_errors_; | 458 ZoneList<Error>* reported_errors_; |
494 int reported_errors_begin_; | 459 int reported_errors_begin_; |
495 int reported_errors_end_; | 460 int reported_errors_end_; |
496 DuplicateFinder* duplicate_finder_; | 461 DuplicateFinder* duplicate_finder_; |
497 }; | 462 }; |
498 | 463 |
499 | 464 |
500 #undef ERROR_CODES | 465 #undef ERROR_CODES |
501 | 466 |
502 | 467 |
503 } // namespace internal | 468 } // namespace internal |
504 } // namespace v8 | 469 } // namespace v8 |
505 | 470 |
506 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H | 471 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H |
OLD | NEW |