OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
6 | 6 |
7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 Type& target_type = Type::Handle(target.RedirectionType()); | 433 Type& target_type = Type::Handle(target.RedirectionType()); |
434 Function& target_target = Function::Handle(target.RedirectionTarget()); | 434 Function& target_target = Function::Handle(target.RedirectionTarget()); |
435 if (target_target.IsNull()) { | 435 if (target_target.IsNull()) { |
436 ASSERT(target_type.IsMalformed()); | 436 ASSERT(target_type.IsMalformed()); |
437 } else { | 437 } else { |
438 // If the target type refers to type parameters, substitute them with the | 438 // If the target type refers to type parameters, substitute them with the |
439 // type arguments of the redirection type. | 439 // type arguments of the redirection type. |
440 if (!target_type.IsInstantiated()) { | 440 if (!target_type.IsInstantiated()) { |
441 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); | 441 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
442 Error& bound_error = Error::Handle(); | 442 Error& bound_error = Error::Handle(); |
443 target_type ^= target_type.InstantiateFrom(type_args, &bound_error); | 443 target_type ^= target_type.InstantiateFrom( |
| 444 type_args, &bound_error, NULL, Heap::kOld); |
444 if (bound_error.IsNull()) { | 445 if (bound_error.IsNull()) { |
445 target_type ^= FinalizeType(cls, target_type, kCanonicalize); | 446 target_type ^= FinalizeType(cls, target_type, kCanonicalize); |
446 } else { | 447 } else { |
447 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); | 448 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); |
448 const Script& script = Script::Handle(target_class.script()); | 449 const Script& script = Script::Handle(target_class.script()); |
449 FinalizeMalformedType(bound_error, script, target_type, | 450 FinalizeMalformedType(bound_error, script, target_type, |
450 "cannot resolve redirecting factory"); | 451 "cannot resolve redirecting factory"); |
451 target_target = Function::null(); | 452 target_target = Function::null(); |
452 } | 453 } |
453 } | 454 } |
454 } | 455 } |
455 factory.SetRedirectionType(target_type); | 456 factory.SetRedirectionType(target_type); |
456 factory.SetRedirectionTarget(target_target); | 457 factory.SetRedirectionTarget(target_target); |
457 } | 458 } |
458 | 459 |
459 | 460 |
460 void ClassFinalizer::ResolveTypeClass(const Class& cls, | 461 RawAbstractType* ClassFinalizer::ResolveTypeClass(const Class& cls, |
461 const AbstractType& type) { | 462 const Type& type) { |
462 if (type.IsFinalized() || type.HasResolvedTypeClass()) { | 463 if (type.IsFinalized()) { |
463 return; | 464 return type.raw(); |
464 } | 465 } |
465 if (FLAG_trace_type_finalization) { | 466 if (FLAG_trace_type_finalization) { |
466 THR_Print("Resolve type class of '%s'\n", | 467 THR_Print("Resolve type class of '%s'\n", |
467 String::Handle(type.Name()).ToCString()); | 468 String::Handle(type.Name()).ToCString()); |
468 } | 469 } |
469 | 470 |
470 // Type parameters are always resolved in the parser in the correct | 471 // Type parameters are always resolved in the parser in the correct |
471 // non-static scope or factory scope. That resolution scope is unknown here. | 472 // non-static scope or factory scope. That resolution scope is unknown here. |
472 // Being able to resolve a type parameter from class cls here would indicate | 473 // Being able to resolve a type parameter from class cls here would indicate |
473 // that the type parameter appeared in a static scope. Leaving the type as | 474 // that the type parameter appeared in a static scope. Leaving the type as |
474 // unresolved is the correct thing to do. | 475 // unresolved is the correct thing to do. |
475 | 476 |
476 // Lookup the type class. | 477 // Lookup the type class if necessary. |
477 const UnresolvedClass& unresolved_class = | 478 Class& type_class = Class::Handle(); |
478 UnresolvedClass::Handle(type.unresolved_class()); | 479 if (type.HasResolvedTypeClass()) { |
479 const Class& type_class = | 480 type_class = type.type_class(); |
480 Class::Handle(ResolveClass(cls, unresolved_class)); | 481 } else { |
481 | 482 const UnresolvedClass& unresolved_class = |
| 483 UnresolvedClass::Handle(type.unresolved_class()); |
| 484 type_class = ResolveClass(cls, unresolved_class); |
| 485 if (type_class.IsNull()) { |
| 486 // The type class could not be resolved. The type is malformed. |
| 487 FinalizeMalformedType( |
| 488 Error::Handle(), // No previous error. |
| 489 Script::Handle(cls.script()), |
| 490 type, |
| 491 "cannot resolve class '%s' from '%s'", |
| 492 String::Handle(unresolved_class.Name()).ToCString(), |
| 493 String::Handle(cls.Name()).ToCString()); |
| 494 return type.raw(); |
| 495 } |
| 496 } |
| 497 // Promote the Type to a FunctionType in case its type class is a typedef. |
| 498 if (type_class.IsTypedefClass()) { |
| 499 return FunctionType::New(type_class, |
| 500 TypeArguments::Handle(type.arguments()), |
| 501 Function::Handle(type_class.signature_function()), |
| 502 type.token_pos()); |
| 503 } |
482 // Replace unresolved class with resolved type class. | 504 // Replace unresolved class with resolved type class. |
483 const Type& parameterized_type = Type::Cast(type); | 505 type.set_type_class(type_class); |
484 if (type_class.IsNull()) { | 506 return type.raw(); |
485 // The type class could not be resolved. The type is malformed. | |
486 FinalizeMalformedType( | |
487 Error::Handle(), // No previous error. | |
488 Script::Handle(cls.script()), | |
489 parameterized_type, | |
490 "cannot resolve class '%s' from '%s'", | |
491 String::Handle(unresolved_class.Name()).ToCString(), | |
492 String::Handle(cls.Name()).ToCString()); | |
493 return; | |
494 } | |
495 parameterized_type.set_type_class(type_class); | |
496 } | 507 } |
497 | 508 |
498 | 509 |
499 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { | 510 RawAbstractType* ClassFinalizer::ResolveType(const Class& cls, |
| 511 const AbstractType& type) { |
500 if (type.IsResolved()) { | 512 if (type.IsResolved()) { |
501 return; | 513 return type.raw(); |
502 } | 514 } |
503 ASSERT(type.IsType()); | |
504 if (FLAG_trace_type_finalization) { | 515 if (FLAG_trace_type_finalization) { |
505 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 516 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
506 } | 517 } |
507 ResolveTypeClass(cls, type); | 518 AbstractType& resolved_type = AbstractType::Handle(); |
508 if (type.IsMalformed()) { | 519 if (type.IsType()) { |
509 ASSERT(type.IsResolved()); | 520 resolved_type = ResolveTypeClass(cls, Type::Cast(type)); |
510 return; | 521 if (resolved_type.IsMalformed()) { |
| 522 ASSERT(resolved_type.IsResolved()); |
| 523 return resolved_type.raw(); |
| 524 } |
| 525 } else { |
| 526 ASSERT(type.IsFunctionType()); |
| 527 const Function& signature = |
| 528 Function::Handle(FunctionType::Cast(type).signature()); |
| 529 ResolveSignature(cls, signature); |
| 530 resolved_type = type.raw(); |
511 } | 531 } |
512 // Mark type as resolved before resolving its type arguments in order to avoid | 532 // Mark type as resolved before resolving its type arguments in order to avoid |
513 // repeating resolution of recursive types. | 533 // repeating resolution of recursive types. |
514 Type::Cast(type).set_is_resolved(); | 534 resolved_type.SetIsResolved(); |
515 // Resolve type arguments, if any. | 535 // Resolve type arguments, if any. |
516 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); | 536 const TypeArguments& arguments = |
| 537 TypeArguments::Handle(resolved_type.arguments()); |
517 if (!arguments.IsNull()) { | 538 if (!arguments.IsNull()) { |
518 const intptr_t num_arguments = arguments.Length(); | 539 const intptr_t num_arguments = arguments.Length(); |
519 AbstractType& type_argument = AbstractType::Handle(); | 540 AbstractType& type_argument = AbstractType::Handle(); |
520 for (intptr_t i = 0; i < num_arguments; i++) { | 541 for (intptr_t i = 0; i < num_arguments; i++) { |
521 type_argument = arguments.TypeAt(i); | 542 type_argument = arguments.TypeAt(i); |
522 ResolveType(cls, type_argument); | 543 type_argument = ResolveType(cls, type_argument); |
| 544 arguments.SetTypeAt(i, type_argument); |
523 } | 545 } |
524 } | 546 } |
| 547 return resolved_type.raw(); |
525 } | 548 } |
526 | 549 |
527 | 550 |
528 void ClassFinalizer::FinalizeTypeParameters( | 551 void ClassFinalizer::FinalizeTypeParameters( |
529 const Class& cls, | 552 const Class& cls, |
530 PendingTypes* pending_types) { | 553 PendingTypes* pending_types) { |
531 if (FLAG_trace_type_finalization) { | 554 if (FLAG_trace_type_finalization) { |
532 THR_Print("Finalizing type parameters of '%s'\n", | 555 THR_Print("Finalizing type parameters of '%s'\n", |
533 String::Handle(cls.Name()).ToCString()); | 556 String::Handle(cls.Name()).ToCString()); |
534 } | 557 } |
(...skipping 22 matching lines...) Expand all Loading... |
557 // finalized is a non-contractive type, i.e. if the induced type set S of P is | 580 // finalized is a non-contractive type, i.e. if the induced type set S of P is |
558 // not finite, where P is the instantiation of T with its own type parameters. | 581 // not finite, where P is the instantiation of T with its own type parameters. |
559 // The induced type set S consists of the super types of any type in S as well | 582 // The induced type set S consists of the super types of any type in S as well |
560 // as the type arguments of any parameterized type in S. | 583 // as the type arguments of any parameterized type in S. |
561 // The Dart Language Specification does not disallow the declaration and use of | 584 // The Dart Language Specification does not disallow the declaration and use of |
562 // non-contractive types (this may change). They are nevertheless disallowed | 585 // non-contractive types (this may change). They are nevertheless disallowed |
563 // as an implementation restriction in the VM since they cause divergence. | 586 // as an implementation restriction in the VM since they cause divergence. |
564 // A non-contractive type can be detected by looking at the queue of types | 587 // A non-contractive type can be detected by looking at the queue of types |
565 // pending finalization that are mutually recursive with the checked type. | 588 // pending finalization that are mutually recursive with the checked type. |
566 void ClassFinalizer::CheckRecursiveType(const Class& cls, | 589 void ClassFinalizer::CheckRecursiveType(const Class& cls, |
567 const Type& type, | 590 const AbstractType& type, |
568 PendingTypes* pending_types) { | 591 PendingTypes* pending_types) { |
569 Zone* zone = Thread::Current()->zone(); | 592 Zone* zone = Thread::Current()->zone(); |
570 if (FLAG_trace_type_finalization) { | 593 if (FLAG_trace_type_finalization) { |
571 THR_Print("Checking recursive type '%s': %s\n", | 594 THR_Print("Checking recursive type '%s': %s\n", |
572 String::Handle(type.Name()).ToCString(), | 595 String::Handle(type.Name()).ToCString(), |
573 type.ToCString()); | 596 type.ToCString()); |
574 } | 597 } |
575 const Class& type_cls = Class::Handle(zone, type.type_class()); | 598 const Class& type_cls = Class::Handle(zone, type.type_class()); |
576 const TypeArguments& arguments = | 599 const TypeArguments& arguments = |
577 TypeArguments::Handle(zone, type.arguments()); | 600 TypeArguments::Handle(zone, type.arguments()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 // Reject the non-contractive recursive type. | 636 // Reject the non-contractive recursive type. |
614 const String& type_name = String::Handle(zone, type.Name()); | 637 const String& type_name = String::Handle(zone, type.Name()); |
615 ReportError(cls, type.token_pos(), | 638 ReportError(cls, type.token_pos(), |
616 "illegal recursive type '%s'", type_name.ToCString()); | 639 "illegal recursive type '%s'", type_name.ToCString()); |
617 } | 640 } |
618 } | 641 } |
619 } | 642 } |
620 } | 643 } |
621 | 644 |
622 | 645 |
| 646 // Expand the type arguments of the given type and finalize its full type |
| 647 // argument vector. Return the number of type arguments (0 for a raw type). |
| 648 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( |
| 649 const Class& cls, |
| 650 const AbstractType& type, |
| 651 PendingTypes* pending_types) { |
| 652 Zone* Z = Thread::Current()->zone(); |
| 653 // The type class does not need to be finalized in order to finalize the type, |
| 654 // however, it must at least be resolved (this was done as part of resolving |
| 655 // the type itself, a precondition to calling FinalizeType). |
| 656 // Also, the interfaces of the type class must be resolved and the type |
| 657 // parameters of the type class must be finalized. |
| 658 Class& type_class = Class::Handle(Z, type.type_class()); |
| 659 if (!type_class.is_type_finalized()) { |
| 660 FinalizeTypeParameters(type_class, pending_types); |
| 661 ResolveUpperBounds(type_class); |
| 662 } |
| 663 |
| 664 // The finalized type argument vector needs num_type_arguments types. |
| 665 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 666 // The class has num_type_parameters type parameters. |
| 667 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 668 |
| 669 // Initialize the type argument vector. |
| 670 // Check the number of parsed type arguments, if any. |
| 671 // Specifying no type arguments indicates a raw type, which is not an error. |
| 672 // However, type parameter bounds are checked below, even for a raw type. |
| 673 TypeArguments& arguments = TypeArguments::Handle(Z, type.arguments()); |
| 674 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 675 // Wrong number of type arguments. The type is mapped to the raw type. |
| 676 if (Isolate::Current()->flags().error_on_bad_type()) { |
| 677 const String& type_class_name = String::Handle(Z, type_class.Name()); |
| 678 ReportError(cls, type.token_pos(), |
| 679 "wrong number of type arguments for class '%s'", |
| 680 type_class_name.ToCString()); |
| 681 } |
| 682 // Make the type raw and continue without reporting any error. |
| 683 // A static warning should have been reported. |
| 684 arguments = TypeArguments::null(); |
| 685 type.set_arguments(arguments); |
| 686 } |
| 687 |
| 688 // Mark the type as being finalized in order to detect self reference and |
| 689 // postpone bound checking until after all types in the graph of |
| 690 // mutually recursive types are finalized. |
| 691 type.SetIsBeingFinalized(); |
| 692 pending_types->Add(type); |
| 693 |
| 694 // The full type argument vector consists of the type arguments of the |
| 695 // super types of type_class, which are initialized from the parsed |
| 696 // type arguments, followed by the parsed type arguments. |
| 697 TypeArguments& full_arguments = TypeArguments::Handle(Z); |
| 698 if (num_type_arguments > 0) { |
| 699 // If no type arguments were parsed and if the super types do not prepend |
| 700 // type arguments to the vector, we can leave the vector as null. |
| 701 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| 702 full_arguments = TypeArguments::New(num_type_arguments); |
| 703 // Copy the parsed type arguments at the correct offset in the full type |
| 704 // argument vector. |
| 705 const intptr_t offset = num_type_arguments - num_type_parameters; |
| 706 AbstractType& type_arg = |
| 707 AbstractType::Handle(Z, Type::DynamicType()); |
| 708 // Leave the temporary type arguments at indices [0..offset[ as null. |
| 709 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 710 // If no type parameters were provided, a raw type is desired, so we |
| 711 // create a vector of dynamic. |
| 712 if (!arguments.IsNull()) { |
| 713 type_arg = arguments.TypeAt(i); |
| 714 // The parsed type_arg may or may not be finalized. |
| 715 } |
| 716 full_arguments.SetTypeAt(offset + i, type_arg); |
| 717 } |
| 718 // Replace the compile-time argument vector (of length zero or |
| 719 // num_type_parameters) of this type being finalized with the still |
| 720 // unfinalized run-time argument vector (of length num_type_arguments). |
| 721 // This type being finalized may be recursively reached via bounds |
| 722 // checking or type arguments of its super type. |
| 723 type.set_arguments(full_arguments); |
| 724 // Finalize the current type arguments of the type, which are still the |
| 725 // parsed type arguments. |
| 726 if (!arguments.IsNull()) { |
| 727 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 728 type_arg = full_arguments.TypeAt(offset + i); |
| 729 ASSERT(!type_arg.IsBeingFinalized()); |
| 730 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); |
| 731 if (type_arg.IsMalformed()) { |
| 732 // Malformed type arguments are mapped to dynamic. |
| 733 type_arg = Type::DynamicType(); |
| 734 } |
| 735 full_arguments.SetTypeAt(offset + i, type_arg); |
| 736 } |
| 737 } |
| 738 if (offset > 0) { |
| 739 TrailPtr trail = new Trail(Z, 4); |
| 740 Error& bound_error = Error::Handle(); |
| 741 FinalizeTypeArguments(type_class, full_arguments, offset, |
| 742 &bound_error, pending_types, trail); |
| 743 } |
| 744 if (full_arguments.IsRaw(0, num_type_arguments)) { |
| 745 // The parameterized_type is raw. Set its argument vector to null, which |
| 746 // is more efficient in type tests. |
| 747 full_arguments = TypeArguments::null(); |
| 748 } |
| 749 type.set_arguments(full_arguments); |
| 750 } else { |
| 751 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
| 752 } |
| 753 } |
| 754 |
| 755 // Self referencing types may get finalized indirectly. |
| 756 if (!type.IsFinalized()) { |
| 757 ASSERT(full_arguments.IsNull() || |
| 758 !full_arguments.IsRaw(0, num_type_arguments)); |
| 759 // Mark the type as finalized. |
| 760 type.SetIsFinalized(); |
| 761 // Do not yet remove the type from the pending_types array. |
| 762 } |
| 763 return full_arguments.IsNull() ? 0 : full_arguments.Length(); |
| 764 } |
| 765 |
| 766 |
623 // Finalize the type argument vector 'arguments' of the type defined by the | 767 // Finalize the type argument vector 'arguments' of the type defined by the |
624 // class 'cls' parameterized with the type arguments 'cls_args'. | 768 // class 'cls' parameterized with the type arguments 'cls_args'. |
625 // The vector 'cls_args' is already initialized as a subvector at the correct | 769 // The vector 'cls_args' is already initialized as a subvector at the correct |
626 // position in the passed in 'arguments' vector. | 770 // position in the passed in 'arguments' vector. |
627 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at | 771 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at |
628 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' | 772 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' |
629 // vector. | 773 // vector. |
630 // The type argument vector of cls may overlap the type argument vector of its | 774 // The type argument vector of cls may overlap the type argument vector of its |
631 // super class. In case of an overlap, the overlapped type arguments of the | 775 // super class. In case of an overlap, the overlapped type arguments of the |
632 // super class are already initialized. The still uninitialized ones have an | 776 // super class are already initialized. The still uninitialized ones have an |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 TypeArguments& super_type_args = TypeArguments::Handle( | 824 TypeArguments& super_type_args = TypeArguments::Handle( |
681 super_type.arguments()); | 825 super_type.arguments()); |
682 // Offset of super type's type parameters in cls' type argument vector. | 826 // Offset of super type's type parameters in cls' type argument vector. |
683 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 827 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
684 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 828 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
685 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 829 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
686 if (!super_type_args.IsNull()) { | 830 if (!super_type_args.IsNull()) { |
687 super_type_arg = super_type_args.TypeAt(i); | 831 super_type_arg = super_type_args.TypeAt(i); |
688 if (!super_type_arg.IsTypeRef()) { | 832 if (!super_type_arg.IsTypeRef()) { |
689 if (super_type_arg.IsBeingFinalized()) { | 833 if (super_type_arg.IsBeingFinalized()) { |
690 ASSERT(super_type_arg.IsType()); | 834 ASSERT(super_type_arg.IsType() || super_type_arg.IsFunctionType()); |
691 CheckRecursiveType(cls, Type::Cast(super_type_arg), pending_types); | 835 CheckRecursiveType(cls, super_type_arg, pending_types); |
692 if (FLAG_trace_type_finalization) { | 836 if (FLAG_trace_type_finalization) { |
693 THR_Print("Creating TypeRef '%s': '%s'\n", | 837 THR_Print("Creating TypeRef '%s': '%s'\n", |
694 String::Handle(super_type_arg.Name()).ToCString(), | 838 String::Handle(super_type_arg.Name()).ToCString(), |
695 super_type_arg.ToCString()); | 839 super_type_arg.ToCString()); |
696 } | 840 } |
697 super_type_arg = TypeRef::New(super_type_arg); | 841 super_type_arg = TypeRef::New(super_type_arg); |
698 super_type_args.SetTypeAt(i, super_type_arg); | 842 super_type_args.SetTypeAt(i, super_type_arg); |
699 } else { | 843 } else { |
700 if (!super_type_arg.IsFinalized()) { | 844 if (!super_type_arg.IsFinalized()) { |
701 super_type_arg ^= FinalizeType( | 845 super_type_arg ^= FinalizeType( |
(...skipping 28 matching lines...) Expand all Loading... |
730 *bound_error = error.raw(); | 874 *bound_error = error.raw(); |
731 } | 875 } |
732 } | 876 } |
733 if (!super_type_arg.IsFinalized() && | 877 if (!super_type_arg.IsFinalized() && |
734 !super_type_arg.IsBeingFinalized()) { | 878 !super_type_arg.IsBeingFinalized()) { |
735 // The super_type_arg was instantiated from a type being finalized. | 879 // The super_type_arg was instantiated from a type being finalized. |
736 // We need to finish finalizing its type arguments. | 880 // We need to finish finalizing its type arguments. |
737 if (super_type_arg.IsTypeRef()) { | 881 if (super_type_arg.IsTypeRef()) { |
738 super_type_arg = TypeRef::Cast(super_type_arg).type(); | 882 super_type_arg = TypeRef::Cast(super_type_arg).type(); |
739 } | 883 } |
740 Type::Cast(super_type_arg).set_is_being_finalized(); | 884 Type::Cast(super_type_arg).SetIsBeingFinalized(); |
741 pending_types->Add(super_type_arg); | 885 pending_types->Add(super_type_arg); |
742 const Class& cls = Class::Handle(super_type_arg.type_class()); | 886 const Class& cls = Class::Handle(super_type_arg.type_class()); |
743 FinalizeTypeArguments( | 887 FinalizeTypeArguments( |
744 cls, | 888 cls, |
745 TypeArguments::Handle(super_type_arg.arguments()), | 889 TypeArguments::Handle(super_type_arg.arguments()), |
746 cls.NumTypeArguments() - cls.NumTypeParameters(), | 890 cls.NumTypeArguments() - cls.NumTypeParameters(), |
747 bound_error, | 891 bound_error, |
748 pending_types, | 892 pending_types, |
749 trail); | 893 trail); |
750 Type::Cast(super_type_arg).SetIsFinalized(); | 894 Type::Cast(super_type_arg).SetIsFinalized(); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 // Shortcut the special case where we check a type parameter against its | 981 // Shortcut the special case where we check a type parameter against its |
838 // declared upper bound. | 982 // declared upper bound. |
839 if (error.IsNull() && | 983 if (error.IsNull() && |
840 !(type_arg.Equals(type_param) && | 984 !(type_arg.Equals(type_param) && |
841 instantiated_bound.Equals(declared_bound))) { | 985 instantiated_bound.Equals(declared_bound))) { |
842 // If type_arg is a type parameter, its declared bound may not be | 986 // If type_arg is a type parameter, its declared bound may not be |
843 // resolved yet. | 987 // resolved yet. |
844 if (type_arg.IsTypeParameter()) { | 988 if (type_arg.IsTypeParameter()) { |
845 const Class& type_arg_cls = Class::Handle( | 989 const Class& type_arg_cls = Class::Handle( |
846 TypeParameter::Cast(type_arg).parameterized_class()); | 990 TypeParameter::Cast(type_arg).parameterized_class()); |
847 const AbstractType& bound = AbstractType::Handle( | 991 AbstractType& bound = AbstractType::Handle( |
848 TypeParameter::Cast(type_arg).bound()); | 992 TypeParameter::Cast(type_arg).bound()); |
849 ResolveType(type_arg_cls, bound); | 993 bound = ResolveType(type_arg_cls, bound); |
| 994 TypeParameter::Cast(type_arg).set_bound(bound); |
850 } | 995 } |
851 // This may be called only if type needs to be finalized, therefore | 996 // This may be called only if type needs to be finalized, therefore |
852 // seems OK to allocate finalized types in old space. | 997 // seems OK to allocate finalized types in old space. |
853 if (!type_param.CheckBound(type_arg, instantiated_bound, | 998 if (!type_param.CheckBound(type_arg, instantiated_bound, |
854 &error, Heap::kOld) && error.IsNull()) { | 999 &error, Heap::kOld) && error.IsNull()) { |
855 // The bound cannot be checked at compile time; postpone to run time. | 1000 // The bound cannot be checked at compile time; postpone to run time. |
856 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 1001 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
857 arguments.SetTypeAt(offset + i, type_arg); | 1002 arguments.SetTypeAt(offset + i, type_arg); |
858 } | 1003 } |
859 } | 1004 } |
860 if (!error.IsNull() && bound_error->IsNull()) { | 1005 if (!error.IsNull() && bound_error->IsNull()) { |
861 *bound_error = error.raw(); | 1006 *bound_error = error.raw(); |
862 } | 1007 } |
863 } | 1008 } |
864 } | 1009 } |
865 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 1010 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
866 if (!super_type.IsNull()) { | 1011 if (!super_type.IsNull()) { |
867 const Class& super_class = Class::Handle(super_type.type_class()); | 1012 const Class& super_class = Class::Handle(super_type.type_class()); |
868 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 1013 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
869 } | 1014 } |
870 } | 1015 } |
871 | 1016 |
872 | 1017 |
873 void ClassFinalizer::CheckTypeBounds(const Class& cls, const Type& type) { | 1018 void ClassFinalizer::CheckTypeBounds(const Class& cls, |
| 1019 const AbstractType& type) { |
| 1020 ASSERT(type.IsType() || type.IsFunctionType()); |
874 ASSERT(type.IsFinalized()); | 1021 ASSERT(type.IsFinalized()); |
875 TypeArguments& arguments = TypeArguments::Handle(type.arguments()); | 1022 TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
876 if (arguments.IsNull()) { | 1023 if (arguments.IsNull()) { |
877 return; | 1024 return; |
878 } | 1025 } |
879 Class& owner_class = Class::Handle(); | 1026 const Class& type_class = Class::Handle(type.type_class()); |
880 Class& type_class = Class::Handle(type.type_class()); | |
881 if (type_class.IsSignatureClass()) { | |
882 const Function& signature_fun = | |
883 Function::Handle(type_class.signature_function()); | |
884 ASSERT(!signature_fun.is_static()); | |
885 owner_class = signature_fun.Owner(); | |
886 } else { | |
887 owner_class = type_class.raw(); | |
888 } | |
889 Error& bound_error = Error::Handle(); | 1027 Error& bound_error = Error::Handle(); |
890 CheckTypeArgumentBounds(owner_class, arguments, &bound_error); | 1028 CheckTypeArgumentBounds(type_class, arguments, &bound_error); |
891 type.set_arguments(arguments); | 1029 type.set_arguments(arguments); |
892 // If a bound error occurred, mark the type as malbounded. | 1030 // If a bound error occurred, mark the type as malbounded. |
893 // The bound error will be ignored in production mode. | 1031 // The bound error will be ignored in production mode. |
894 if (!bound_error.IsNull()) { | 1032 if (!bound_error.IsNull()) { |
895 // No compile-time error during finalization. | 1033 // No compile-time error during finalization. |
896 const String& type_name = String::Handle(type.UserVisibleName()); | 1034 const String& type_name = String::Handle(type.UserVisibleName()); |
897 FinalizeMalboundedType(bound_error, | 1035 FinalizeMalboundedType(bound_error, |
898 Script::Handle(cls.script()), | 1036 Script::Handle(cls.script()), |
899 type, | 1037 type, |
900 "type '%s' has an out of bound type argument", | 1038 "type '%s' has an out of bound type argument", |
(...skipping 28 matching lines...) Expand all Loading... |
929 if (type.IsTypeRef()) { | 1067 if (type.IsTypeRef()) { |
930 // The referenced type will be finalized later by the code that set the | 1068 // The referenced type will be finalized later by the code that set the |
931 // is_being_finalized mark bit. | 1069 // is_being_finalized mark bit. |
932 return type.raw(); | 1070 return type.raw(); |
933 } | 1071 } |
934 | 1072 |
935 // Recursive types must be processed in FinalizeTypeArguments() and cannot be | 1073 // Recursive types must be processed in FinalizeTypeArguments() and cannot be |
936 // encountered here. | 1074 // encountered here. |
937 ASSERT(!type.IsBeingFinalized()); | 1075 ASSERT(!type.IsBeingFinalized()); |
938 | 1076 |
| 1077 Zone* Z = Thread::Current()->zone(); |
| 1078 const AbstractType& resolved_type = |
| 1079 AbstractType::Handle(Z, ResolveType(cls, type)); |
939 // A malformed type gets mapped to a finalized type. | 1080 // A malformed type gets mapped to a finalized type. |
940 ResolveType(cls, type); | 1081 if (resolved_type.IsMalformed()) { |
941 if (type.IsMalformed()) { | 1082 ASSERT(resolved_type.IsFinalized()); |
942 ASSERT(type.IsFinalized()); | 1083 return resolved_type.raw(); |
943 return type.raw(); | |
944 } | 1084 } |
945 | 1085 |
946 Zone* Z = Thread::Current()->zone(); | |
947 if (FLAG_trace_type_finalization) { | 1086 if (FLAG_trace_type_finalization) { |
948 THR_Print("Finalizing type '%s' for class '%s'\n", | 1087 THR_Print("Finalizing type '%s' for class '%s'\n", |
949 String::Handle(Z, type.Name()).ToCString(), | 1088 String::Handle(Z, resolved_type.Name()).ToCString(), |
950 cls.ToCString()); | 1089 cls.ToCString()); |
951 } | 1090 } |
952 | 1091 |
953 if (type.IsTypeParameter()) { | 1092 if (resolved_type.IsTypeParameter()) { |
954 const TypeParameter& type_parameter = TypeParameter::Cast(type); | 1093 const TypeParameter& type_parameter = TypeParameter::Cast(resolved_type); |
955 const Class& parameterized_class = | 1094 const Class& parameterized_class = |
956 Class::Handle(Z, type_parameter.parameterized_class()); | 1095 Class::Handle(Z, type_parameter.parameterized_class()); |
957 ASSERT(!parameterized_class.IsNull()); | 1096 ASSERT(!parameterized_class.IsNull()); |
958 // The index must reflect the position of this type parameter in the type | 1097 // The index must reflect the position of this type parameter in the type |
959 // arguments vector of its parameterized class. The offset to add is the | 1098 // arguments vector of its parameterized class. The offset to add is the |
960 // number of type arguments in the super type, which is equal to the | 1099 // number of type arguments in the super type, which is equal to the |
961 // difference in number of type arguments and type parameters of the | 1100 // difference in number of type arguments and type parameters of the |
962 // parameterized class. | 1101 // parameterized class. |
963 const intptr_t offset = parameterized_class.NumTypeArguments() - | 1102 const intptr_t offset = parameterized_class.NumTypeArguments() - |
964 parameterized_class.NumTypeParameters(); | 1103 parameterized_class.NumTypeParameters(); |
965 // Calling NumTypeParameters() may finalize this type parameter if it | 1104 // Calling NumTypeParameters() may finalize this type parameter if it |
966 // belongs to a mixin application class. | 1105 // belongs to a mixin application class. |
967 if (!type_parameter.IsFinalized()) { | 1106 if (!type_parameter.IsFinalized()) { |
968 type_parameter.set_index(type_parameter.index() + offset); | 1107 type_parameter.set_index(type_parameter.index() + offset); |
969 type_parameter.set_is_finalized(); | 1108 type_parameter.SetIsFinalized(); |
970 } else { | 1109 } else { |
971 ASSERT(cls.IsMixinApplication()); | 1110 ASSERT(cls.IsMixinApplication()); |
972 } | 1111 } |
973 | 1112 |
974 if (FLAG_trace_type_finalization) { | 1113 if (FLAG_trace_type_finalization) { |
975 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", | 1114 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
976 String::Handle(Z, type_parameter.name()).ToCString(), | 1115 String::Handle(Z, type_parameter.name()).ToCString(), |
977 type_parameter.index()); | 1116 type_parameter.index()); |
978 } | 1117 } |
979 | 1118 |
980 // We do not canonicalize type parameters. | 1119 // We do not canonicalize type parameters. |
981 return type_parameter.raw(); | 1120 return type_parameter.raw(); |
982 } | 1121 } |
983 | 1122 |
984 // At this point, we can only have a parameterized_type. | 1123 // At this point, we can only have a Type or a FunctionType. |
985 const Type& parameterized_type = Type::Cast(type); | 1124 ASSERT(resolved_type.IsType() || resolved_type.IsFunctionType()); |
986 | 1125 |
987 // This type is the root type of the type graph if no pending types queue is | 1126 // This type is the root type of the type graph if no pending types queue is |
988 // allocated yet. | 1127 // allocated yet. |
989 const bool is_root_type = (pending_types == NULL); | 1128 const bool is_root_type = (pending_types == NULL); |
990 if (is_root_type) { | 1129 if (is_root_type) { |
991 pending_types = new PendingTypes(Z, 4); | 1130 pending_types = new PendingTypes(Z, 4); |
992 } | 1131 } |
993 | 1132 |
994 // The type class does not need to be finalized in order to finalize the type, | 1133 const intptr_t num_expanded_type_arguments = |
995 // however, it must at least be resolved (this was done as part of resolving | 1134 ExpandAndFinalizeTypeArguments(cls, resolved_type, pending_types); |
996 // the type itself, a precondition to calling FinalizeType). | |
997 // Also, the interfaces of the type class must be resolved and the type | |
998 // parameters of the type class must be finalized. | |
999 Class& type_class = Class::Handle(Z, parameterized_type.type_class()); | |
1000 if (!type_class.is_type_finalized()) { | |
1001 FinalizeTypeParameters(type_class, pending_types); | |
1002 ResolveUpperBounds(type_class); | |
1003 } | |
1004 | |
1005 // The finalized type argument vector needs num_type_arguments types. | |
1006 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | |
1007 // The type class has num_type_parameters type parameters. | |
1008 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | |
1009 | |
1010 // Initialize the type argument vector. | |
1011 // Check the number of parsed type arguments, if any. | |
1012 // Specifying no type arguments indicates a raw type, which is not an error. | |
1013 // However, type parameter bounds are checked below, even for a raw type. | |
1014 TypeArguments& arguments = | |
1015 TypeArguments::Handle(Z, parameterized_type.arguments()); | |
1016 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | |
1017 // Wrong number of type arguments. The type is mapped to the raw type. | |
1018 if (Isolate::Current()->flags().error_on_bad_type()) { | |
1019 const String& type_class_name = | |
1020 String::Handle(Z, type_class.Name()); | |
1021 ReportError(cls, parameterized_type.token_pos(), | |
1022 "wrong number of type arguments for class '%s'", | |
1023 type_class_name.ToCString()); | |
1024 } | |
1025 // Make the type raw and continue without reporting any error. | |
1026 // A static warning should have been reported. | |
1027 arguments = TypeArguments::null(); | |
1028 parameterized_type.set_arguments(arguments); | |
1029 } | |
1030 | |
1031 // Mark the type as being finalized in order to detect self reference and | |
1032 // postpone bound checking until after all types in the graph of | |
1033 // mutually recursive types are finalized. | |
1034 parameterized_type.set_is_being_finalized(); | |
1035 pending_types->Add(parameterized_type); | |
1036 | |
1037 // The full type argument vector consists of the type arguments of the | |
1038 // super types of type_class, which are initialized from the parsed | |
1039 // type arguments, followed by the parsed type arguments. | |
1040 TypeArguments& full_arguments = TypeArguments::Handle(Z); | |
1041 Error& bound_error = Error::Handle(Z); | |
1042 if (num_type_arguments > 0) { | |
1043 // If no type arguments were parsed and if the super types do not prepend | |
1044 // type arguments to the vector, we can leave the vector as null. | |
1045 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | |
1046 full_arguments = TypeArguments::New(num_type_arguments); | |
1047 // Copy the parsed type arguments at the correct offset in the full type | |
1048 // argument vector. | |
1049 const intptr_t offset = num_type_arguments - num_type_parameters; | |
1050 AbstractType& type_arg = | |
1051 AbstractType::Handle(Z, Type::DynamicType()); | |
1052 // Leave the temporary type arguments at indices [0..offset[ as null. | |
1053 for (intptr_t i = 0; i < num_type_parameters; i++) { | |
1054 // If no type parameters were provided, a raw type is desired, so we | |
1055 // create a vector of dynamic. | |
1056 if (!arguments.IsNull()) { | |
1057 type_arg = arguments.TypeAt(i); | |
1058 // The parsed type_arg may or may not be finalized. | |
1059 } | |
1060 full_arguments.SetTypeAt(offset + i, type_arg); | |
1061 } | |
1062 // Replace the compile-time argument vector (of length zero or | |
1063 // num_type_parameters) of this type being finalized with the still | |
1064 // unfinalized run-time argument vector (of length num_type_arguments). | |
1065 // This type being finalized may be recursively reached via bounds | |
1066 // checking or type arguments of its super type. | |
1067 parameterized_type.set_arguments(full_arguments); | |
1068 // Finalize the current type arguments of the type, which are still the | |
1069 // parsed type arguments. | |
1070 if (!arguments.IsNull()) { | |
1071 for (intptr_t i = 0; i < num_type_parameters; i++) { | |
1072 type_arg = full_arguments.TypeAt(offset + i); | |
1073 ASSERT(!type_arg.IsBeingFinalized()); | |
1074 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); | |
1075 if (type_arg.IsMalformed()) { | |
1076 // Malformed type arguments are mapped to dynamic. | |
1077 type_arg = Type::DynamicType(); | |
1078 } | |
1079 full_arguments.SetTypeAt(offset + i, type_arg); | |
1080 } | |
1081 } | |
1082 // If the type class is a signature class, the full argument vector | |
1083 // must include the argument vector of the super type. | |
1084 // If the signature class is a function type alias, it is also the owner | |
1085 // of its signature function and no super type is involved. | |
1086 // If the signature class is canonical (not an alias), the owner of its | |
1087 // signature function may either be an alias or the enclosing class of a | |
1088 // local function, in which case the super type of the enclosing class is | |
1089 // also considered when filling up the argument vector. | |
1090 Class& owner_class = Class::Handle(Z); | |
1091 if (type_class.IsSignatureClass()) { | |
1092 const Function& signature_fun = | |
1093 Function::Handle(Z, type_class.signature_function()); | |
1094 ASSERT(!signature_fun.is_static()); | |
1095 owner_class = signature_fun.Owner(); | |
1096 } else { | |
1097 owner_class = type_class.raw(); | |
1098 } | |
1099 if (offset > 0) { | |
1100 TrailPtr trail = new Trail(Z, 4); | |
1101 FinalizeTypeArguments(owner_class, full_arguments, offset, | |
1102 &bound_error, pending_types, trail); | |
1103 } | |
1104 if (full_arguments.IsRaw(0, num_type_arguments)) { | |
1105 // The parameterized_type is raw. Set its argument vector to null, which | |
1106 // is more efficient in type tests. | |
1107 full_arguments = TypeArguments::null(); | |
1108 } | |
1109 parameterized_type.set_arguments(full_arguments); | |
1110 } else { | |
1111 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | |
1112 } | |
1113 } | |
1114 | |
1115 // Self referencing types may get finalized indirectly. | |
1116 if (!parameterized_type.IsFinalized()) { | |
1117 ASSERT(full_arguments.IsNull() || | |
1118 !full_arguments.IsRaw(0, num_type_arguments)); | |
1119 // Mark the type as finalized. | |
1120 parameterized_type.SetIsFinalized(); | |
1121 // Do not yet remove the type from the pending_types array. | |
1122 } | |
1123 | 1135 |
1124 // If we are done finalizing a graph of mutually recursive types, check their | 1136 // If we are done finalizing a graph of mutually recursive types, check their |
1125 // bounds. | 1137 // bounds. |
1126 if (is_root_type) { | 1138 if (is_root_type) { |
1127 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { | 1139 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { |
1128 CheckTypeBounds(cls, Type::Cast(pending_types->At(i))); | 1140 CheckTypeBounds(cls, pending_types->At(i)); |
1129 if (FLAG_trace_type_finalization && type.IsRecursive()) { | 1141 if (FLAG_trace_type_finalization && resolved_type.IsRecursive()) { |
1130 THR_Print("Done finalizing recursive type '%s': %s\n", | 1142 THR_Print("Done finalizing recursive type '%s': %s\n", |
1131 String::Handle(Z, type.Name()).ToCString(), | 1143 String::Handle(Z, resolved_type.Name()).ToCString(), |
1132 type.ToCString()); | 1144 resolved_type.ToCString()); |
1133 } | 1145 } |
1134 } | 1146 } |
1135 } | 1147 } |
1136 | 1148 |
1137 // If the type class is a signature class, we are currently finalizing a | 1149 // If the type is a FunctionType, we also need to finalize the types in its |
1138 // signature type, i.e. finalizing the result type and parameter types of the | 1150 // signature, i.e. finalize the result type and parameter types of the |
1139 // signature function of this signature type. | 1151 // signature function of this function type. |
1140 // We do this after marking this type as finalized in order to allow a | 1152 // We do this after marking this type as finalized in order to allow a |
1141 // function type to refer to itself via its parameter types and result type. | 1153 // function type to refer to itself via its parameter types and result type. |
1142 if (type_class.IsSignatureClass()) { | 1154 // Note that we do not instantiate these types according to the type |
1143 // The class may be created while parsing a function body, after all | 1155 // arguments. This will happen on demand when executing a type test. |
1144 // pending classes have already been finalized. | 1156 if (resolved_type.IsFunctionType()) { |
1145 FinalizeTypesInClass(type_class); | 1157 const Function& signature = |
| 1158 Function::Handle(Z, FunctionType::Cast(resolved_type).signature()); |
| 1159 FinalizeSignature(cls, signature); |
1146 } | 1160 } |
1147 | 1161 |
1148 if (FLAG_trace_type_finalization) { | 1162 if (FLAG_trace_type_finalization) { |
1149 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1163 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
1150 String::Handle(Z, parameterized_type.Name()).ToCString(), | 1164 String::Handle(Z, resolved_type.Name()).ToCString(), |
1151 parameterized_type.arguments() == TypeArguments::null() ? | 1165 num_expanded_type_arguments, |
1152 0 : num_type_arguments, | 1166 resolved_type.ToCString()); |
1153 parameterized_type.ToCString()); | |
1154 } | 1167 } |
1155 | 1168 |
1156 if (finalization >= kCanonicalize) { | 1169 if (finalization >= kCanonicalize) { |
1157 if (FLAG_trace_type_finalization && parameterized_type.IsRecursive()) { | 1170 if (FLAG_trace_type_finalization && resolved_type.IsRecursive()) { |
1158 AbstractType& type = Type::Handle(Z); | 1171 AbstractType& recursive_type = |
1159 type = parameterized_type.Canonicalize(); | 1172 AbstractType::Handle(Z, resolved_type.Canonicalize()); |
1160 THR_Print("Done canonicalizing recursive type '%s': %s\n", | 1173 THR_Print("Done canonicalizing recursive type '%s': %s\n", |
1161 String::Handle(Z, type.Name()).ToCString(), | 1174 String::Handle(Z, recursive_type.Name()).ToCString(), |
1162 type.ToCString()); | 1175 recursive_type.ToCString()); |
1163 return type.raw(); | 1176 return recursive_type.raw(); |
1164 } | 1177 } |
1165 return parameterized_type.Canonicalize(); | 1178 return resolved_type.Canonicalize(); |
1166 } else { | 1179 } else { |
1167 return parameterized_type.raw(); | 1180 return resolved_type.raw(); |
1168 } | 1181 } |
1169 } | 1182 } |
1170 | 1183 |
1171 | 1184 |
1172 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 1185 void ClassFinalizer::ResolveSignature(const Class& cls, |
1173 const Function& function) { | 1186 const Function& function) { |
1174 // Resolve result type. | 1187 // Resolve result type. |
1175 AbstractType& type = AbstractType::Handle(function.result_type()); | 1188 AbstractType& type = AbstractType::Handle(function.result_type()); |
1176 // It is not a compile time error if this name does not resolve to a class or | 1189 // It is not a compile time error if this name does not resolve to a class or |
1177 // interface. | 1190 // interface. |
| 1191 AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type)); |
| 1192 if (resolved_type.raw() != type.raw()) { |
| 1193 function.set_result_type(resolved_type); |
| 1194 } |
| 1195 // Resolve formal parameter types. |
| 1196 const intptr_t num_parameters = function.NumParameters(); |
| 1197 for (intptr_t i = 0; i < num_parameters; i++) { |
| 1198 type = function.ParameterTypeAt(i); |
| 1199 resolved_type = ResolveType(cls, type); |
| 1200 if (resolved_type.raw() != type.raw()) { |
| 1201 function.SetParameterTypeAt(i, resolved_type); |
| 1202 } |
| 1203 } |
| 1204 } |
| 1205 |
| 1206 |
| 1207 void ClassFinalizer::FinalizeSignature(const Class& cls, |
| 1208 const Function& function) { |
| 1209 // Finalize result type. |
| 1210 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 1211 // It is not a compile time error if this name does not resolve to a class or |
| 1212 // interface. |
1178 AbstractType& finalized_type = | 1213 AbstractType& finalized_type = |
1179 AbstractType::Handle(FinalizeType(cls, type, kCanonicalize)); | 1214 AbstractType::Handle(FinalizeType(cls, type, kCanonicalize)); |
1180 // The result type may be malformed or malbounded. | 1215 // The result type may be malformed or malbounded. |
1181 if (type.raw() != finalized_type.raw()) { | 1216 if (finalized_type.raw() != type.raw()) { |
1182 function.set_result_type(finalized_type); | 1217 function.set_result_type(finalized_type); |
1183 } | 1218 } |
1184 // Resolve formal parameter types. | 1219 // Finalize formal parameter types. |
1185 const intptr_t num_parameters = function.NumParameters(); | 1220 const intptr_t num_parameters = function.NumParameters(); |
1186 for (intptr_t i = 0; i < num_parameters; i++) { | 1221 for (intptr_t i = 0; i < num_parameters; i++) { |
1187 type = function.ParameterTypeAt(i); | 1222 type = function.ParameterTypeAt(i); |
1188 finalized_type = FinalizeType(cls, type, kCanonicalize); | 1223 finalized_type = FinalizeType(cls, type, kCanonicalize); |
1189 // The parameter type may be malformed or malbounded. | 1224 // The parameter type may be malformed or malbounded. |
1190 if (type.raw() != finalized_type.raw()) { | 1225 if (type.raw() != finalized_type.raw()) { |
1191 function.SetParameterTypeAt(i, finalized_type); | 1226 function.SetParameterTypeAt(i, finalized_type); |
1192 } | 1227 } |
1193 } | 1228 } |
1194 } | 1229 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 AbstractType& bound = AbstractType::Handle(); | 1283 AbstractType& bound = AbstractType::Handle(); |
1249 const TypeArguments& type_params = | 1284 const TypeArguments& type_params = |
1250 TypeArguments::Handle(cls.type_parameters()); | 1285 TypeArguments::Handle(cls.type_parameters()); |
1251 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1286 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
1252 (type_params.Length() == num_type_params)); | 1287 (type_params.Length() == num_type_params)); |
1253 // In a first pass, resolve all bounds. This guarantees that finalization | 1288 // In a first pass, resolve all bounds. This guarantees that finalization |
1254 // of mutually referencing bounds will not encounter an unresolved bound. | 1289 // of mutually referencing bounds will not encounter an unresolved bound. |
1255 for (intptr_t i = 0; i < num_type_params; i++) { | 1290 for (intptr_t i = 0; i < num_type_params; i++) { |
1256 type_param ^= type_params.TypeAt(i); | 1291 type_param ^= type_params.TypeAt(i); |
1257 bound = type_param.bound(); | 1292 bound = type_param.bound(); |
1258 ResolveType(cls, bound); | 1293 bound = ResolveType(cls, bound); |
| 1294 type_param.set_bound(bound); |
1259 } | 1295 } |
1260 } | 1296 } |
1261 | 1297 |
1262 | 1298 |
1263 // Finalize the upper bounds of the type parameters of class cls. | 1299 // Finalize the upper bounds of the type parameters of class cls. |
1264 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { | 1300 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { |
1265 const intptr_t num_type_params = cls.NumTypeParameters(); | 1301 const intptr_t num_type_params = cls.NumTypeParameters(); |
1266 TypeParameter& type_param = TypeParameter::Handle(); | 1302 TypeParameter& type_param = TypeParameter::Handle(); |
1267 AbstractType& bound = AbstractType::Handle(); | 1303 AbstractType& bound = AbstractType::Handle(); |
1268 const TypeArguments& type_params = | 1304 const TypeArguments& type_params = |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1438 } | 1474 } |
1439 // Resolve function signatures and check for conflicts in super classes and | 1475 // Resolve function signatures and check for conflicts in super classes and |
1440 // interfaces. | 1476 // interfaces. |
1441 array = cls.functions(); | 1477 array = cls.functions(); |
1442 Function& function = Function::Handle(Z); | 1478 Function& function = Function::Handle(Z); |
1443 Function& overridden_function = Function::Handle(Z); | 1479 Function& overridden_function = Function::Handle(Z); |
1444 const intptr_t num_functions = array.Length(); | 1480 const intptr_t num_functions = array.Length(); |
1445 Error& error = Error::Handle(Z); | 1481 Error& error = Error::Handle(Z); |
1446 for (intptr_t i = 0; i < num_functions; i++) { | 1482 for (intptr_t i = 0; i < num_functions; i++) { |
1447 function ^= array.At(i); | 1483 function ^= array.At(i); |
1448 ResolveAndFinalizeSignature(cls, function); | 1484 FinalizeSignature(cls, function); |
1449 name = function.name(); | 1485 name = function.name(); |
1450 // Report signature conflicts only. | 1486 // Report signature conflicts only. |
1451 if (Isolate::Current()->flags().error_on_bad_override() && | 1487 if (Isolate::Current()->flags().error_on_bad_override() && |
1452 !function.is_static() && !function.IsGenerativeConstructor()) { | 1488 !function.is_static() && !function.IsGenerativeConstructor()) { |
1453 // A constructor cannot override anything. | 1489 // A constructor cannot override anything. |
1454 for (intptr_t i = 0; i < interfaces.length(); i++) { | 1490 for (intptr_t i = 0; i < interfaces.length(); i++) { |
1455 const Class* super_class = interfaces.At(i); | 1491 const Class* super_class = interfaces.At(i); |
1456 // Finalize superclass since overrides check relies on all members | 1492 // Finalize superclass since overrides check relies on all members |
1457 // of the superclass to be finalized. | 1493 // of the superclass to be finalized. |
1458 FinalizeClass(*super_class); | 1494 FinalizeClass(*super_class); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1711 param ^= mixin_type_args.TypeAt(i); | 1747 param ^= mixin_type_args.TypeAt(i); |
1712 param_bound = param.bound(); | 1748 param_bound = param.bound(); |
1713 if (!param_bound.IsInstantiated()) { | 1749 if (!param_bound.IsInstantiated()) { |
1714 // Make sure the bound is finalized before instantiating it. | 1750 // Make sure the bound is finalized before instantiating it. |
1715 if (!param_bound.IsFinalized() && | 1751 if (!param_bound.IsFinalized() && |
1716 !param_bound.IsBeingFinalized()) { | 1752 !param_bound.IsBeingFinalized()) { |
1717 param_bound = | 1753 param_bound = |
1718 FinalizeType(mixin_app_class, param_bound, kCanonicalize); | 1754 FinalizeType(mixin_app_class, param_bound, kCanonicalize); |
1719 param.set_bound(param_bound); // In case part of recursive type. | 1755 param.set_bound(param_bound); // In case part of recursive type. |
1720 } | 1756 } |
1721 param_bound = param_bound.InstantiateFrom(instantiator, | 1757 param_bound = param_bound.InstantiateFrom( |
1722 &bound_error); | 1758 instantiator, &bound_error, NULL, Heap::kOld); |
1723 // The instantiator contains only TypeParameter objects and no | 1759 // The instantiator contains only TypeParameter objects and no |
1724 // BoundedType objects, so no bound error may occur. | 1760 // BoundedType objects, so no bound error may occur. |
1725 ASSERT(!param_bound.IsBoundedType()); | 1761 ASSERT(!param_bound.IsBoundedType()); |
1726 ASSERT(bound_error.IsNull()); | 1762 ASSERT(bound_error.IsNull()); |
1727 ASSERT(!param_bound.IsInstantiated()); | 1763 ASSERT(!param_bound.IsInstantiated()); |
1728 param.set_bound(param_bound); | 1764 param.set_bound(param_bound); |
1729 } | 1765 } |
1730 } | 1766 } |
1731 } | 1767 } |
1732 | 1768 |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 const intptr_t offset = | 1976 const intptr_t offset = |
1941 mixin_class_super_type_args.Length() - num_aliased_mixin_type_params; | 1977 mixin_class_super_type_args.Length() - num_aliased_mixin_type_params; |
1942 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1978 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
1943 type = mixin_class_super_type_args.TypeAt(offset + i); | 1979 type = mixin_class_super_type_args.TypeAt(offset + i); |
1944 if (!type.IsInstantiated()) { | 1980 if (!type.IsInstantiated()) { |
1945 // In the presence of bounds, the bounded type and the upper bound must | 1981 // In the presence of bounds, the bounded type and the upper bound must |
1946 // be instantiated separately. Instantiating a BoundedType would wrap | 1982 // be instantiated separately. Instantiating a BoundedType would wrap |
1947 // the BoundedType in another BoundedType. | 1983 // the BoundedType in another BoundedType. |
1948 if (type.IsBoundedType()) { | 1984 if (type.IsBoundedType()) { |
1949 bounded_type = BoundedType::Cast(type).type(); | 1985 bounded_type = BoundedType::Cast(type).type(); |
1950 bounded_type = bounded_type.InstantiateFrom(instantiator, | 1986 bounded_type = bounded_type.InstantiateFrom( |
1951 &bound_error); | 1987 instantiator, &bound_error, NULL, Heap::kOld); |
1952 // The instantiator contains only TypeParameter objects and no | 1988 // The instantiator contains only TypeParameter objects and no |
1953 // BoundedType objects, so no bound error may occur. | 1989 // BoundedType objects, so no bound error may occur. |
1954 ASSERT(bound_error.IsNull()); | 1990 ASSERT(bound_error.IsNull()); |
1955 upper_bound = BoundedType::Cast(type).bound(); | 1991 upper_bound = BoundedType::Cast(type).bound(); |
1956 upper_bound = upper_bound.InstantiateFrom(instantiator, &bound_error); | 1992 upper_bound = upper_bound.InstantiateFrom( |
| 1993 instantiator, &bound_error, NULL, Heap::kOld); |
1957 ASSERT(bound_error.IsNull()); | 1994 ASSERT(bound_error.IsNull()); |
1958 type_parameter = BoundedType::Cast(type).type_parameter(); | 1995 type_parameter = BoundedType::Cast(type).type_parameter(); |
1959 // The type parameter that declared the bound does not change. | 1996 // The type parameter that declared the bound does not change. |
1960 type = BoundedType::New(bounded_type, upper_bound, type_parameter); | 1997 type = BoundedType::New(bounded_type, upper_bound, type_parameter); |
1961 } else { | 1998 } else { |
1962 type = type.InstantiateFrom(instantiator, &bound_error); | 1999 type = type.InstantiateFrom( |
| 2000 instantiator, &bound_error, NULL, Heap::kOld); |
1963 ASSERT(bound_error.IsNull()); | 2001 ASSERT(bound_error.IsNull()); |
1964 } | 2002 } |
1965 } | 2003 } |
1966 new_mixin_type_args.SetTypeAt(i, type); | 2004 new_mixin_type_args.SetTypeAt(i, type); |
1967 } | 2005 } |
1968 } | 2006 } |
1969 TypeArguments& new_super_type_args = TypeArguments::Handle(zone); | 2007 TypeArguments& new_super_type_args = TypeArguments::Handle(zone); |
1970 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { | 2008 if ((num_super_type_params + num_aliased_mixin_type_params) > 0) { |
1971 new_super_type_args = TypeArguments::New(num_super_type_params + | 2009 new_super_type_args = TypeArguments::New(num_super_type_params + |
1972 num_aliased_mixin_type_params); | 2010 num_aliased_mixin_type_params); |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2238 if (!super_class.IsNull()) { | 2276 if (!super_class.IsNull()) { |
2239 FinalizeTypesInClass(super_class); | 2277 FinalizeTypesInClass(super_class); |
2240 } | 2278 } |
2241 // Finalize type parameters before finalizing the super type. | 2279 // Finalize type parameters before finalizing the super type. |
2242 FinalizeTypeParameters(cls); // May change super type. | 2280 FinalizeTypeParameters(cls); // May change super type. |
2243 super_class = cls.SuperClass(); | 2281 super_class = cls.SuperClass(); |
2244 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); | 2282 ASSERT(super_class.IsNull() || super_class.is_type_finalized()); |
2245 // Only resolving rather than finalizing the upper bounds here would result in | 2283 // Only resolving rather than finalizing the upper bounds here would result in |
2246 // instantiated type parameters of the super type to temporarily have | 2284 // instantiated type parameters of the super type to temporarily have |
2247 // unfinalized bounds. It is more efficient to finalize them early. | 2285 // unfinalized bounds. It is more efficient to finalize them early. |
| 2286 // Finalize bounds even if running in production mode, so that a snapshot |
| 2287 // contains them. |
2248 FinalizeUpperBounds(cls); | 2288 FinalizeUpperBounds(cls); |
2249 // Finalize super type. | 2289 // Finalize super type. |
2250 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 2290 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
2251 if (!super_type.IsNull()) { | 2291 if (!super_type.IsNull()) { |
2252 // In case of a bound error in the super type in production mode, the | 2292 // In case of a bound error in the super type in production mode, the |
2253 // finalized super type will have a BoundedType as type argument for the | 2293 // finalized super type will have a BoundedType as type argument for the |
2254 // out of bound type argument. | 2294 // out of bound type argument. |
2255 // It should not be a problem if the class is written to a snapshot and | 2295 // It should not be a problem if the class is written to a snapshot and |
2256 // later executed in checked mode. Note that the finalized type argument | 2296 // later executed in checked mode. Note that the finalized type argument |
2257 // vector of any type of the base class will contain a BoundedType for the | 2297 // vector of any type of the base class will contain a BoundedType for the |
2258 // out of bound type argument. | 2298 // out of bound type argument. |
2259 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); | 2299 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); |
2260 cls.set_super_type(super_type); | 2300 cls.set_super_type(super_type); |
2261 } | 2301 } |
2262 // Finalize mixin type. | 2302 // Finalize mixin type. |
2263 Type& mixin_type = Type::Handle(cls.mixin()); | 2303 Type& mixin_type = Type::Handle(cls.mixin()); |
2264 if (!mixin_type.IsNull()) { | 2304 if (!mixin_type.IsNull()) { |
2265 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); | 2305 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); |
2266 cls.set_mixin(mixin_type); | 2306 cls.set_mixin(mixin_type); |
2267 } | 2307 } |
2268 if (cls.IsSignatureClass()) { | 2308 if (cls.IsTypedefClass()) { |
| 2309 const Function& signature = Function::Handle(cls.signature_function()); |
| 2310 FunctionType& type = FunctionType::Handle(signature.SignatureType()); |
| 2311 |
2269 // Check for illegal self references. | 2312 // Check for illegal self references. |
2270 GrowableArray<intptr_t> visited_aliases; | 2313 GrowableArray<intptr_t> visited_aliases; |
2271 if (!IsAliasCycleFree(cls, &visited_aliases)) { | 2314 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { |
2272 const String& name = String::Handle(cls.Name()); | 2315 const String& name = String::Handle(cls.Name()); |
2273 ReportError(cls, cls.token_pos(), | 2316 ReportError(cls, cls.token_pos(), |
2274 "typedef '%s' illegally refers to itself", | 2317 "typedef '%s' illegally refers to itself", |
2275 name.ToCString()); | 2318 name.ToCString()); |
2276 } | 2319 } |
2277 cls.set_is_type_finalized(); | 2320 cls.set_is_type_finalized(); |
2278 | 2321 |
2279 // The type parameters of signature classes may have bounds. | 2322 // Resolve and finalize the result and parameter types of the signature |
2280 FinalizeUpperBounds(cls); | 2323 // function of this typedef class. |
| 2324 FinalizeSignature(cls, signature); // Does not modify signature type. |
| 2325 ASSERT(signature.SignatureType() == type.raw()); |
2281 | 2326 |
2282 // Resolve and finalize the result and parameter types of the signature | 2327 // Resolve and finalize the signature type of this typedef. |
2283 // function of this signature class. | 2328 type ^= FinalizeType(cls, type, kCanonicalizeWellFormed); |
2284 const Function& sig_function = Function::Handle(cls.signature_function()); | 2329 signature.SetSignatureType(type); |
2285 ResolveAndFinalizeSignature(cls, sig_function); | |
2286 | 2330 |
2287 // Resolve and finalize the signature type of this signature class. | 2331 // Closure instances do not refer to this typedef as their class, so there |
2288 const Type& sig_type = Type::Handle(cls.SignatureType()); | 2332 // is no need to add this typedef class to the subclasses of _Closure. |
2289 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); | 2333 ASSERT(super_type.IsNull() || super_type.IsObjectType()); |
2290 | 2334 |
2291 // Add this class to the subclasses of the superclass (_FunctionImpl). | |
2292 if (!super_type.IsNull()) { | |
2293 ASSERT(!super_type.IsObjectType()); | |
2294 ASSERT(!super_class.IsNull()); | |
2295 super_class.AddDirectSubclass(cls); | |
2296 } | |
2297 return; | 2335 return; |
2298 } | 2336 } |
| 2337 |
2299 // Finalize interface types (but not necessarily interface classes). | 2338 // Finalize interface types (but not necessarily interface classes). |
2300 Array& interface_types = Array::Handle(cls.interfaces()); | 2339 Array& interface_types = Array::Handle(cls.interfaces()); |
2301 AbstractType& interface_type = AbstractType::Handle(); | 2340 AbstractType& interface_type = AbstractType::Handle(); |
2302 AbstractType& seen_interf = AbstractType::Handle(); | 2341 AbstractType& seen_interf = AbstractType::Handle(); |
2303 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 2342 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
2304 interface_type ^= interface_types.At(i); | 2343 interface_type ^= interface_types.At(i); |
2305 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); | 2344 interface_type = FinalizeType(cls, interface_type, kCanonicalizeWellFormed); |
2306 interface_types.SetAt(i, interface_type); | 2345 interface_types.SetAt(i, interface_type); |
2307 | 2346 |
2308 // Check whether the interface is duplicated. We need to wait with | 2347 // Check whether the interface is duplicated. We need to wait with |
(...skipping 16 matching lines...) Expand all Loading... |
2325 "interface '%s' appears twice in " | 2364 "interface '%s' appears twice in " |
2326 "implements clause of class '%s'", | 2365 "implements clause of class '%s'", |
2327 String::Handle(interface_type.Name()).ToCString(), | 2366 String::Handle(interface_type.Name()).ToCString(), |
2328 String::Handle(cls.Name()).ToCString()); | 2367 String::Handle(cls.Name()).ToCString()); |
2329 } | 2368 } |
2330 } | 2369 } |
2331 } | 2370 } |
2332 // Mark as type finalized before resolving type parameter upper bounds | 2371 // Mark as type finalized before resolving type parameter upper bounds |
2333 // in order to break cycles. | 2372 // in order to break cycles. |
2334 cls.set_is_type_finalized(); | 2373 cls.set_is_type_finalized(); |
2335 // Finalize bounds even if running in production mode, so that a snapshot | |
2336 // contains them. | |
2337 FinalizeUpperBounds(cls); | |
2338 // Add this class to the direct subclasses of the superclass, unless the | 2374 // Add this class to the direct subclasses of the superclass, unless the |
2339 // superclass is Object. | 2375 // superclass is Object. |
2340 if (!super_type.IsNull() && !super_type.IsObjectType()) { | 2376 if (!super_type.IsNull() && !super_type.IsObjectType()) { |
2341 ASSERT(!super_class.IsNull()); | 2377 ASSERT(!super_class.IsNull()); |
2342 super_class.AddDirectSubclass(cls); | 2378 super_class.AddDirectSubclass(cls); |
2343 } | 2379 } |
2344 // A top level class is parsed eagerly so just finalize it. | 2380 // A top level class is parsed eagerly so just finalize it. |
2345 if (cls.IsTopLevel()) { | 2381 if (cls.IsTopLevel()) { |
2346 FinalizeClass(cls); | 2382 FinalizeClass(cls); |
2347 } else { | 2383 } else { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 | 2430 |
2395 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); | 2431 const Class& mixin_app_class = Class::Handle(cls.SuperClass()); |
2396 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | 2432 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
2397 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); | 2433 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); |
2398 | 2434 |
2399 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); | 2435 CreateForwardingConstructors(cls, mixin_cls, cloned_funcs); |
2400 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); | 2436 const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs)); |
2401 cls.SetFunctions(functions); | 2437 cls.SetFunctions(functions); |
2402 } | 2438 } |
2403 // Every class should have at least a constructor, unless it is a top level | 2439 // Every class should have at least a constructor, unless it is a top level |
2404 // class or a signature class. | 2440 // class or a typedef class. |
2405 ASSERT(cls.IsTopLevel() || | 2441 ASSERT(cls.IsTopLevel() || |
2406 cls.IsSignatureClass() || | 2442 cls.IsTypedefClass() || |
2407 (Array::Handle(cls.functions()).Length() > 0)); | 2443 (Array::Handle(cls.functions()).Length() > 0)); |
2408 // Resolve and finalize all member types. | 2444 // Resolve and finalize all member types. |
2409 ResolveAndFinalizeMemberTypes(cls); | 2445 ResolveAndFinalizeMemberTypes(cls); |
2410 // Run additional checks after all types are finalized. | 2446 // Run additional checks after all types are finalized. |
2411 if (cls.is_const()) { | 2447 if (cls.is_const()) { |
2412 CheckForLegalConstClass(cls); | 2448 CheckForLegalConstClass(cls); |
2413 } | 2449 } |
2414 if (FLAG_use_cha_deopt) { | 2450 if (FLAG_use_cha_deopt) { |
2415 GrowableArray<intptr_t> cids; | 2451 GrowableArray<intptr_t> cids; |
2416 CollectFinalizedSuperClasses(cls, &cids); | 2452 CollectFinalizedSuperClasses(cls, &cids); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2487 test2 = test2.SuperClass(); | 2523 test2 = test2.SuperClass(); |
2488 if (!test2.IsNull()) { | 2524 if (!test2.IsNull()) { |
2489 test2 = test2.SuperClass(); | 2525 test2 = test2.SuperClass(); |
2490 } | 2526 } |
2491 } | 2527 } |
2492 // No cycles. | 2528 // No cycles. |
2493 return true; | 2529 return true; |
2494 } | 2530 } |
2495 | 2531 |
2496 | 2532 |
2497 // Helper function called by IsAliasCycleFree. | 2533 // Returns false if a function type alias illegally refers to itself. |
2498 bool ClassFinalizer::IsTypeCycleFree( | 2534 bool ClassFinalizer::IsTypedefCycleFree(const Class& cls, |
2499 const Class& cls, | 2535 const AbstractType& type, |
2500 const AbstractType& type, | 2536 GrowableArray<intptr_t>* visited) { |
2501 GrowableArray<intptr_t>* visited) { | |
2502 ASSERT(visited != NULL); | 2537 ASSERT(visited != NULL); |
2503 ResolveType(cls, type); | 2538 AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type)); |
2504 if (type.IsType() && !type.IsMalformed()) { | 2539 bool checking_typedef = false; |
2505 const Class& type_class = Class::Handle(type.type_class()); | 2540 if ((resolved_type.IsType() || resolved_type.IsFunctionType()) && |
2506 if (!type_class.is_type_finalized() && | 2541 !resolved_type.IsMalformed()) { |
2507 type_class.IsSignatureClass() && | 2542 AbstractType& other_type = AbstractType::Handle(); |
2508 !IsAliasCycleFree(type_class, visited)) { | 2543 if (resolved_type.IsFunctionType()) { |
2509 return false; | 2544 const Class& scope_class = Class::Handle(resolved_type.type_class()); |
2510 } | 2545 if (!scope_class.is_type_finalized() && scope_class.IsTypedefClass()) { |
2511 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); | 2546 checking_typedef = true; |
2512 if (!type_args.IsNull()) { | 2547 const intptr_t scope_class_id = scope_class.id(); |
2513 AbstractType& type_arg = AbstractType::Handle(); | 2548 ASSERT(visited != NULL); |
2514 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2549 for (intptr_t i = 0; i < visited->length(); i++) { |
2515 type_arg = type_args.TypeAt(i); | 2550 if ((*visited)[i] == scope_class_id) { |
2516 if (!IsTypeCycleFree(cls, type_arg, visited)) { | 2551 // We have already visited alias 'scope_class'. We found a cycle. |
| 2552 return false; |
| 2553 } |
| 2554 } |
| 2555 visited->Add(scope_class_id); |
| 2556 } |
| 2557 // Check the bounds of this function type. |
| 2558 const intptr_t num_type_params = scope_class.NumTypeParameters(); |
| 2559 TypeParameter& type_param = TypeParameter::Handle(); |
| 2560 const TypeArguments& type_params = |
| 2561 TypeArguments::Handle(scope_class.type_parameters()); |
| 2562 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
| 2563 (type_params.Length() == num_type_params)); |
| 2564 for (intptr_t i = 0; i < num_type_params; i++) { |
| 2565 type_param ^= type_params.TypeAt(i); |
| 2566 other_type = type_param.bound(); |
| 2567 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
2517 return false; | 2568 return false; |
2518 } | 2569 } |
2519 } | 2570 } |
| 2571 // Check the result type of the signature of this function type. |
| 2572 const Function& function = |
| 2573 Function::Handle(FunctionType::Cast(resolved_type).signature()); |
| 2574 other_type = function.result_type(); |
| 2575 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
| 2576 return false; |
| 2577 } |
| 2578 // Check the parameter types of the signature of this function type. |
| 2579 const intptr_t num_parameters = function.NumParameters(); |
| 2580 for (intptr_t i = 0; i < num_parameters; i++) { |
| 2581 other_type = function.ParameterTypeAt(i); |
| 2582 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
| 2583 return false; |
| 2584 } |
| 2585 } |
| 2586 } |
| 2587 const TypeArguments& type_args = |
| 2588 TypeArguments::Handle(resolved_type.arguments()); |
| 2589 if (!type_args.IsNull()) { |
| 2590 for (intptr_t i = 0; i < type_args.Length(); i++) { |
| 2591 other_type = type_args.TypeAt(i); |
| 2592 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
| 2593 return false; |
| 2594 } |
| 2595 } |
| 2596 } |
| 2597 if (checking_typedef) { |
| 2598 visited->RemoveLast(); |
2520 } | 2599 } |
2521 } | 2600 } |
2522 return true; | 2601 return true; |
2523 } | 2602 } |
2524 | 2603 |
2525 | |
2526 // Returns false if the function type alias illegally refers to itself. | |
2527 bool ClassFinalizer::IsAliasCycleFree(const Class& cls, | |
2528 GrowableArray<intptr_t>* visited) { | |
2529 ASSERT(cls.IsSignatureClass()); | |
2530 ASSERT(!cls.is_type_finalized()); | |
2531 ASSERT(visited != NULL); | |
2532 const intptr_t cls_index = cls.id(); | |
2533 for (intptr_t i = 0; i < visited->length(); i++) { | |
2534 if ((*visited)[i] == cls_index) { | |
2535 // We have already visited alias 'cls'. We found a cycle. | |
2536 return false; | |
2537 } | |
2538 } | |
2539 | |
2540 // Visit the bounds, result type, and parameter types of this signature type. | |
2541 visited->Add(cls.id()); | |
2542 AbstractType& type = AbstractType::Handle(); | |
2543 | |
2544 // Check the bounds of this signature type. | |
2545 const intptr_t num_type_params = cls.NumTypeParameters(); | |
2546 TypeParameter& type_param = TypeParameter::Handle(); | |
2547 const TypeArguments& type_params = | |
2548 TypeArguments::Handle(cls.type_parameters()); | |
2549 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | |
2550 (type_params.Length() == num_type_params)); | |
2551 for (intptr_t i = 0; i < num_type_params; i++) { | |
2552 type_param ^= type_params.TypeAt(i); | |
2553 type = type_param.bound(); | |
2554 if (!IsTypeCycleFree(cls, type, visited)) { | |
2555 return false; | |
2556 } | |
2557 } | |
2558 // Check the result type of the function of this signature type. | |
2559 const Function& function = Function::Handle(cls.signature_function()); | |
2560 type = function.result_type(); | |
2561 if (!IsTypeCycleFree(cls, type, visited)) { | |
2562 return false; | |
2563 } | |
2564 // Check the formal parameter types of the function of this signature type. | |
2565 const intptr_t num_parameters = function.NumParameters(); | |
2566 for (intptr_t i = 0; i < num_parameters; i++) { | |
2567 type = function.ParameterTypeAt(i); | |
2568 if (!IsTypeCycleFree(cls, type, visited)) { | |
2569 return false; | |
2570 } | |
2571 } | |
2572 visited->RemoveLast(); | |
2573 return true; | |
2574 } | |
2575 | |
2576 | 2604 |
2577 // Returns false if the mixin illegally refers to itself. | 2605 // Returns false if the mixin illegally refers to itself. |
2578 bool ClassFinalizer::IsMixinCycleFree(const Class& cls, | 2606 bool ClassFinalizer::IsMixinCycleFree(const Class& cls, |
2579 GrowableArray<intptr_t>* visited) { | 2607 GrowableArray<intptr_t>* visited) { |
2580 ASSERT(visited != NULL); | 2608 ASSERT(visited != NULL); |
2581 const intptr_t cls_index = cls.id(); | 2609 const intptr_t cls_index = cls.id(); |
2582 for (intptr_t i = 0; i < visited->length(); i++) { | 2610 for (intptr_t i = 0; i < visited->length(); i++) { |
2583 if ((*visited)[i] == cls_index) { | 2611 if ((*visited)[i] == cls_index) { |
2584 // We have already visited mixin 'cls'. We found a cycle. | 2612 // We have already visited mixin 'cls'. We found a cycle. |
2585 return false; | 2613 return false; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2650 // and resolve super type and mixin types. | 2678 // and resolve super type and mixin types. |
2651 Zone* zone = Thread::Current()->zone(); | 2679 Zone* zone = Thread::Current()->zone(); |
2652 const Library& library = Library::Handle(zone, cls.library()); | 2680 const Library& library = Library::Handle(zone, cls.library()); |
2653 ASSERT(!library.IsNull()); | 2681 ASSERT(!library.IsNull()); |
2654 const Script& script = Script::Handle(zone, cls.script()); | 2682 const Script& script = Script::Handle(zone, cls.script()); |
2655 ASSERT(!script.IsNull()); | 2683 ASSERT(!script.IsNull()); |
2656 const GrowableObjectArray& type_args = | 2684 const GrowableObjectArray& type_args = |
2657 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 2685 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
2658 AbstractType& mixin_super_type = | 2686 AbstractType& mixin_super_type = |
2659 AbstractType::Handle(zone, mixin_app_type.super_type()); | 2687 AbstractType::Handle(zone, mixin_app_type.super_type()); |
2660 ResolveType(cls, mixin_super_type); | 2688 mixin_super_type = ResolveType(cls, mixin_super_type); |
2661 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. | 2689 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
2662 if (mixin_super_type.IsMalformedOrMalbounded()) { | 2690 if (mixin_super_type.IsMalformedOrMalbounded()) { |
2663 ReportError(Error::Handle(zone, mixin_super_type.error())); | 2691 ReportError(Error::Handle(zone, mixin_super_type.error())); |
2664 } | 2692 } |
2665 if (mixin_super_type.IsDynamicType()) { | 2693 if (mixin_super_type.IsDynamicType()) { |
2666 ReportError(cls, cls.token_pos(), | 2694 ReportError(cls, cls.token_pos(), |
2667 "class '%s' may not extend 'dynamic'", | 2695 "class '%s' may not extend 'dynamic'", |
2668 String::Handle(zone, cls.Name()).ToCString()); | 2696 String::Handle(zone, cls.Name()).ToCString()); |
2669 } | 2697 } |
2670 // The super type may have a BoundedType as type argument, but cannot be | 2698 // The super type may have a BoundedType as type argument, but cannot be |
2671 // a BoundedType itself. | 2699 // a BoundedType itself. |
2672 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2700 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
2673 AbstractType& mixin_type = AbstractType::Handle(zone); | 2701 AbstractType& mixin_type = AbstractType::Handle(zone); |
2674 Class& mixin_type_class = Class::Handle(zone); | 2702 Class& mixin_type_class = Class::Handle(zone); |
2675 Class& mixin_app_class = Class::Handle(zone); | 2703 Class& mixin_app_class = Class::Handle(zone); |
2676 String& mixin_app_class_name = String::Handle(zone); | 2704 String& mixin_app_class_name = String::Handle(zone); |
2677 String& mixin_type_class_name = String::Handle(zone); | 2705 String& mixin_type_class_name = String::Handle(zone); |
2678 AbstractType& super_type_arg = AbstractType::Handle(zone); | 2706 AbstractType& super_type_arg = AbstractType::Handle(zone); |
2679 AbstractType& mixin_type_arg = AbstractType::Handle(zone); | 2707 AbstractType& mixin_type_arg = AbstractType::Handle(zone); |
2680 const intptr_t depth = mixin_app_type.Depth(); | 2708 const intptr_t depth = mixin_app_type.Depth(); |
2681 for (intptr_t i = 0; i < depth; i++) { | 2709 for (intptr_t i = 0; i < depth; i++) { |
2682 mixin_type = mixin_app_type.MixinTypeAt(i); | 2710 mixin_type = mixin_app_type.MixinTypeAt(i); |
2683 ASSERT(!mixin_type.IsNull()); | 2711 ASSERT(!mixin_type.IsNull()); |
2684 ResolveType(cls, mixin_type); | 2712 mixin_type = ResolveType(cls, mixin_type); |
2685 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. | 2713 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
2686 ASSERT(mixin_type.IsType()); | 2714 ASSERT(mixin_type.IsType()); |
2687 const intptr_t num_super_type_args = type_args.Length(); | 2715 const intptr_t num_super_type_args = type_args.Length(); |
2688 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2716 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
2689 | 2717 |
2690 // If the mixin type has identical type arguments as the super type, they | 2718 // If the mixin type has identical type arguments as the super type, they |
2691 // can share the same type parameters of the mixin application class, | 2719 // can share the same type parameters of the mixin application class, |
2692 // thereby allowing for further optimizations, such as instantiator vector | 2720 // thereby allowing for further optimizations, such as instantiator vector |
2693 // reuse or sharing of type arguments with the super class. | 2721 // reuse or sharing of type arguments with the super class. |
2694 bool share_type_params = (num_super_type_args > 0) && | 2722 bool share_type_params = (num_super_type_args > 0) && |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2835 // If cls belongs to core lib, restrictions about allowed interfaces | 2863 // If cls belongs to core lib, restrictions about allowed interfaces |
2836 // are lifted. | 2864 // are lifted. |
2837 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); | 2865 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); |
2838 | 2866 |
2839 // Resolve and check the super type and interfaces of cls. | 2867 // Resolve and check the super type and interfaces of cls. |
2840 visited->Add(cls_index); | 2868 visited->Add(cls_index); |
2841 AbstractType& interface = AbstractType::Handle(zone); | 2869 AbstractType& interface = AbstractType::Handle(zone); |
2842 Class& interface_class = Class::Handle(zone); | 2870 Class& interface_class = Class::Handle(zone); |
2843 | 2871 |
2844 // Resolve super type. Failures lead to a longjmp. | 2872 // Resolve super type. Failures lead to a longjmp. |
2845 ResolveType(cls, super_type); | 2873 super_type = ResolveType(cls, super_type); |
2846 if (super_type.IsMalformedOrMalbounded()) { | 2874 if (super_type.IsMalformedOrMalbounded()) { |
2847 ReportError(Error::Handle(zone, super_type.error())); | 2875 ReportError(Error::Handle(zone, super_type.error())); |
2848 } | 2876 } |
2849 if (super_type.IsDynamicType()) { | 2877 if (super_type.IsDynamicType()) { |
2850 ReportError(cls, cls.token_pos(), | 2878 ReportError(cls, cls.token_pos(), |
2851 "class '%s' may not extend 'dynamic'", | 2879 "class '%s' may not extend 'dynamic'", |
2852 String::Handle(zone, cls.Name()).ToCString()); | 2880 String::Handle(zone, cls.Name()).ToCString()); |
2853 } | 2881 } |
2854 interface_class = super_type.type_class(); | 2882 interface_class = super_type.type_class(); |
2855 if (interface_class.IsSignatureClass()) { | 2883 if (interface_class.IsTypedefClass()) { |
2856 ReportError(cls, cls.token_pos(), | 2884 ReportError(cls, cls.token_pos(), |
2857 "class '%s' may not extend function type alias '%s'", | 2885 "class '%s' may not extend function type alias '%s'", |
2858 String::Handle(zone, cls.Name()).ToCString(), | 2886 String::Handle(zone, cls.Name()).ToCString(), |
2859 String::Handle(zone, | 2887 String::Handle(zone, |
2860 super_type.UserVisibleName()).ToCString()); | 2888 super_type.UserVisibleName()).ToCString()); |
2861 } | 2889 } |
2862 if (interface_class.is_enum_class()) { | 2890 if (interface_class.is_enum_class()) { |
2863 ReportError(cls, cls.token_pos(), | 2891 ReportError(cls, cls.token_pos(), |
2864 "class '%s' may not extend enum '%s'", | 2892 "class '%s' may not extend enum '%s'", |
2865 String::Handle(zone, cls.Name()).ToCString(), | 2893 String::Handle(zone, cls.Name()).ToCString(), |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2915 String::Handle(zone, cls.Name()).ToCString(), | 2943 String::Handle(zone, cls.Name()).ToCString(), |
2916 interface_name.ToCString()); | 2944 interface_name.ToCString()); |
2917 } | 2945 } |
2918 } | 2946 } |
2919 // Now resolve the super interfaces of the super type. | 2947 // Now resolve the super interfaces of the super type. |
2920 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2948 ResolveSuperTypeAndInterfaces(interface_class, visited); |
2921 | 2949 |
2922 // Resolve interfaces. Failures lead to a longjmp. | 2950 // Resolve interfaces. Failures lead to a longjmp. |
2923 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 2951 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
2924 interface ^= super_interfaces.At(i); | 2952 interface ^= super_interfaces.At(i); |
2925 ResolveType(cls, interface); | 2953 interface = ResolveType(cls, interface); |
2926 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 2954 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
2927 // A malbounded interface is only reported when involved in a type test. | 2955 // A malbounded interface is only reported when involved in a type test. |
2928 if (interface.IsMalformed()) { | 2956 if (interface.IsMalformed()) { |
2929 ReportError(Error::Handle(zone, interface.error())); | 2957 ReportError(Error::Handle(zone, interface.error())); |
2930 } | 2958 } |
2931 if (interface.IsDynamicType()) { | 2959 if (interface.IsDynamicType()) { |
2932 ReportError(cls, cls.token_pos(), | 2960 ReportError(cls, cls.token_pos(), |
2933 "'dynamic' may not be used as interface"); | 2961 "'dynamic' may not be used as interface"); |
2934 } | 2962 } |
2935 interface_class = interface.type_class(); | 2963 interface_class = interface.type_class(); |
2936 if (interface_class.IsSignatureClass()) { | 2964 if (interface_class.IsTypedefClass()) { |
2937 const String& interface_name = String::Handle(zone, | 2965 const String& interface_name = String::Handle(zone, |
2938 interface_class.Name()); | 2966 interface_class.Name()); |
2939 ReportError(cls, cls.token_pos(), | 2967 ReportError(cls, cls.token_pos(), |
2940 "function type alias '%s' may not be used as interface", | 2968 "function type alias '%s' may not be used as interface", |
2941 interface_name.ToCString()); | 2969 interface_name.ToCString()); |
2942 } | 2970 } |
2943 if (interface_class.is_enum_class()) { | 2971 if (interface_class.is_enum_class()) { |
2944 const String& interface_name = String::Handle(zone, | 2972 const String& interface_name = String::Handle(zone, |
2945 interface_class.Name()); | 2973 interface_class.Name()); |
2946 ReportError(cls, cls.token_pos(), | 2974 ReportError(cls, cls.token_pos(), |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3062 if (Isolate::Current()->flags().error_on_bad_type()) { | 3090 if (Isolate::Current()->flags().error_on_bad_type()) { |
3063 ReportError(error); | 3091 ReportError(error); |
3064 } | 3092 } |
3065 type.set_error(error); | 3093 type.set_error(error); |
3066 // Make the type raw, since it may not be possible to | 3094 // Make the type raw, since it may not be possible to |
3067 // properly finalize its type arguments. | 3095 // properly finalize its type arguments. |
3068 type.set_type_class(Class::Handle(Object::dynamic_class())); | 3096 type.set_type_class(Class::Handle(Object::dynamic_class())); |
3069 type.set_arguments(Object::null_type_arguments()); | 3097 type.set_arguments(Object::null_type_arguments()); |
3070 if (!type.IsFinalized()) { | 3098 if (!type.IsFinalized()) { |
3071 type.SetIsFinalized(); | 3099 type.SetIsFinalized(); |
3072 // Do not canonicalize malformed types, since they may not be resolved. | 3100 // Do not canonicalize malformed types, since they contain an error field. |
3073 } else { | 3101 } else { |
3074 // The only case where the malformed type was already finalized is when its | 3102 // The only case where the malformed type was already finalized is when its |
3075 // type arguments are not within bounds. In that case, we have a prev_error. | 3103 // type arguments are not within bounds. In that case, we have a prev_error. |
3076 ASSERT(!prev_error.IsNull()); | 3104 ASSERT(!prev_error.IsNull()); |
3077 } | 3105 } |
3078 } | 3106 } |
3079 | 3107 |
3080 | 3108 |
3081 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, | 3109 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, |
3082 const Script& script, | 3110 const Script& script, |
(...skipping 21 matching lines...) Expand all Loading... |
3104 const char* format, ...) { | 3132 const char* format, ...) { |
3105 va_list args; | 3133 va_list args; |
3106 va_start(args, format); | 3134 va_start(args, format); |
3107 MarkTypeMalformed(prev_error, script, type, format, args); | 3135 MarkTypeMalformed(prev_error, script, type, format, args); |
3108 va_end(args); | 3136 va_end(args); |
3109 } | 3137 } |
3110 | 3138 |
3111 | 3139 |
3112 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, | 3140 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error, |
3113 const Script& script, | 3141 const Script& script, |
3114 const Type& type, | 3142 const AbstractType& type, |
3115 const char* format, ...) { | 3143 const char* format, ...) { |
3116 va_list args; | 3144 va_list args; |
3117 va_start(args, format); | 3145 va_start(args, format); |
3118 LanguageError& error = LanguageError::Handle( | 3146 LanguageError& error = LanguageError::Handle( |
3119 LanguageError::NewFormattedV( | 3147 LanguageError::NewFormattedV( |
3120 prev_error, script, type.token_pos(), Report::AtLocation, | 3148 prev_error, script, type.token_pos(), Report::AtLocation, |
3121 Report::kMalboundedType, Heap::kOld, | 3149 Report::kMalboundedType, Heap::kOld, |
3122 format, args)); | 3150 format, args)); |
3123 va_end(args); | 3151 va_end(args); |
3124 if (Isolate::Current()->flags().error_on_bad_type()) { | 3152 if (Isolate::Current()->flags().error_on_bad_type()) { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3232 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3260 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3233 field ^= fields_array.At(0); | 3261 field ^= fields_array.At(0); |
3234 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3262 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3235 name ^= field.name(); | 3263 name ^= field.name(); |
3236 expected_name ^= String::New("_data"); | 3264 expected_name ^= String::New("_data"); |
3237 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3265 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3238 #endif | 3266 #endif |
3239 } | 3267 } |
3240 | 3268 |
3241 } // namespace dart | 3269 } // namespace dart |
OLD | NEW |