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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 "cannot resolve redirecting factory"); | 449 "cannot resolve redirecting factory"); |
450 target_target = Function::null(); | 450 target_target = Function::null(); |
451 } | 451 } |
452 } | 452 } |
453 } | 453 } |
454 factory.SetRedirectionType(target_type); | 454 factory.SetRedirectionType(target_type); |
455 factory.SetRedirectionTarget(target_target); | 455 factory.SetRedirectionTarget(target_target); |
456 } | 456 } |
457 | 457 |
458 | 458 |
459 RawAbstractType* ClassFinalizer::ResolveTypeClass(const Class& cls, | 459 void ClassFinalizer::ResolveTypeClass(const Class& cls, const Type& type) { |
460 const Type& type) { | |
461 if (type.IsFinalized()) { | 460 if (type.IsFinalized()) { |
462 return type.raw(); | 461 return; |
463 } | 462 } |
464 if (FLAG_trace_type_finalization) { | 463 if (FLAG_trace_type_finalization) { |
465 THR_Print("Resolve type class of '%s'\n", | 464 THR_Print("Resolve type class of '%s'\n", |
466 String::Handle(type.Name()).ToCString()); | 465 String::Handle(type.Name()).ToCString()); |
467 } | 466 } |
468 | 467 |
469 // Type parameters are always resolved in the parser in the correct | 468 // Type parameters are always resolved in the parser in the correct |
470 // non-static scope or factory scope. That resolution scope is unknown here. | 469 // non-static scope or factory scope. That resolution scope is unknown here. |
471 // Being able to resolve a type parameter from class cls here would indicate | 470 // Being able to resolve a type parameter from class cls here would indicate |
472 // that the type parameter appeared in a static scope. Leaving the type as | 471 // that the type parameter appeared in a static scope. Leaving the type as |
473 // unresolved is the correct thing to do. | 472 // unresolved is the correct thing to do. |
474 | 473 |
475 // Lookup the type class if necessary. | 474 // Lookup the type class if necessary. |
476 Class& type_class = Class::Handle(); | 475 Class& type_class = Class::Handle(); |
477 if (type.HasResolvedTypeClass()) { | 476 if (type.HasResolvedTypeClass()) { |
478 type_class = type.type_class(); | 477 type_class = type.type_class(); |
479 } else { | 478 } else { |
480 const UnresolvedClass& unresolved_class = | 479 const UnresolvedClass& unresolved_class = |
481 UnresolvedClass::Handle(type.unresolved_class()); | 480 UnresolvedClass::Handle(type.unresolved_class()); |
482 type_class = ResolveClass(cls, unresolved_class); | 481 type_class = ResolveClass(cls, unresolved_class); |
483 if (type_class.IsNull()) { | 482 if (type_class.IsNull()) { |
484 // The type class could not be resolved. The type is malformed. | 483 // The type class could not be resolved. The type is malformed. |
485 FinalizeMalformedType( | 484 FinalizeMalformedType( |
486 Error::Handle(), // No previous error. | 485 Error::Handle(), // No previous error. |
487 Script::Handle(cls.script()), | 486 Script::Handle(cls.script()), |
488 type, | 487 type, |
489 "cannot resolve class '%s' from '%s'", | 488 "cannot resolve class '%s' from '%s'", |
490 String::Handle(unresolved_class.Name()).ToCString(), | 489 String::Handle(unresolved_class.Name()).ToCString(), |
491 String::Handle(cls.Name()).ToCString()); | 490 String::Handle(cls.Name()).ToCString()); |
492 return type.raw(); | 491 return; |
493 } | 492 } |
| 493 // Replace unresolved class with resolved type class. |
| 494 type.set_type_class(type_class); |
494 } | 495 } |
495 // Promote the Type to a FunctionType in case its type class is a typedef. | 496 // Promote the type to a function type in case its type class is a typedef. |
496 if (type_class.IsTypedefClass()) { | 497 // Note that the type may already be a function type if it was parsed as a |
497 return FunctionType::New(type_class, | 498 // formal parameter function type. |
498 TypeArguments::Handle(type.arguments()), | 499 if (!type.IsFunctionType() && |
499 Function::Handle(type_class.signature_function()), | 500 type_class.IsTypedefClass() && |
500 type.token_pos()); | 501 !type.IsMalformedOrMalbounded()) { |
| 502 type.set_signature(Function::Handle(type_class.signature_function())); |
501 } | 503 } |
502 // Replace unresolved class with resolved type class. | 504 ASSERT(!type_class.IsTypedefClass() || |
503 type.set_type_class(type_class); | 505 (type.signature() != Function::null())); |
504 return type.raw(); | |
505 } | 506 } |
506 | 507 |
507 | 508 |
508 RawAbstractType* ClassFinalizer::ResolveType(const Class& cls, | 509 void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) { |
509 const AbstractType& type) { | |
510 if (type.IsResolved()) { | 510 if (type.IsResolved()) { |
511 return type.raw(); | 511 return; |
512 } | 512 } |
513 if (FLAG_trace_type_finalization) { | 513 if (FLAG_trace_type_finalization) { |
514 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 514 THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
515 } | 515 } |
516 AbstractType& resolved_type = AbstractType::Handle(); | |
517 if (type.IsType()) { | 516 if (type.IsType()) { |
518 resolved_type = ResolveTypeClass(cls, Type::Cast(type)); | 517 ResolveTypeClass(cls, Type::Cast(type)); |
519 if (resolved_type.IsMalformed()) { | 518 if (type.IsMalformed()) { |
520 ASSERT(resolved_type.IsResolved()); | 519 ASSERT(type.IsResolved()); |
521 return resolved_type.raw(); | 520 return; |
522 } | 521 } |
523 } else { | 522 } |
524 ASSERT(type.IsFunctionType()); | 523 // Mark type as resolved before resolving its type arguments and, in case of a |
525 const Function& signature = | 524 // function type, its signature, in order to avoid cycles. |
526 Function::Handle(FunctionType::Cast(type).signature()); | 525 type.SetIsResolved(); |
527 const Class& scope_class = | 526 // Resolve type arguments, if any. |
528 Class::Handle(FunctionType::Cast(type).scope_class()); | 527 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
| 528 if (!arguments.IsNull()) { |
| 529 const intptr_t num_arguments = arguments.Length(); |
| 530 AbstractType& type_argument = AbstractType::Handle(); |
| 531 for (intptr_t i = 0; i < num_arguments; i++) { |
| 532 type_argument = arguments.TypeAt(i); |
| 533 ResolveType(cls, type_argument); |
| 534 } |
| 535 } |
| 536 // Resolve signature if function type. |
| 537 if (type.IsFunctionType()) { |
| 538 const Function& signature = Function::Handle(Type::Cast(type).signature()); |
| 539 const Class& scope_class = Class::Handle(type.type_class()); |
529 if (scope_class.IsTypedefClass()) { | 540 if (scope_class.IsTypedefClass()) { |
530 ResolveSignature(scope_class, signature); | 541 ResolveSignature(scope_class, signature); |
531 } else { | 542 } else { |
532 ResolveSignature(cls, signature); | 543 ResolveSignature(cls, signature); |
533 } | 544 } |
534 resolved_type = type.raw(); | |
535 } | 545 } |
536 // Mark type as resolved before resolving its type arguments in order to avoid | |
537 // repeating resolution of recursive types. | |
538 resolved_type.SetIsResolved(); | |
539 // Resolve type arguments, if any. | |
540 const TypeArguments& arguments = | |
541 TypeArguments::Handle(resolved_type.arguments()); | |
542 if (!arguments.IsNull()) { | |
543 const intptr_t num_arguments = arguments.Length(); | |
544 AbstractType& type_argument = AbstractType::Handle(); | |
545 for (intptr_t i = 0; i < num_arguments; i++) { | |
546 type_argument = arguments.TypeAt(i); | |
547 type_argument = ResolveType(cls, type_argument); | |
548 arguments.SetTypeAt(i, type_argument); | |
549 } | |
550 } | |
551 return resolved_type.raw(); | |
552 } | 546 } |
553 | 547 |
554 | 548 |
555 void ClassFinalizer::FinalizeTypeParameters( | 549 void ClassFinalizer::FinalizeTypeParameters( |
556 const Class& cls, | 550 const Class& cls, |
557 PendingTypes* pending_types) { | 551 PendingTypes* pending_types) { |
558 if (FLAG_trace_type_finalization) { | 552 if (FLAG_trace_type_finalization) { |
559 THR_Print("Finalizing type parameters of '%s'\n", | 553 THR_Print("Finalizing type parameters of '%s'\n", |
560 String::Handle(cls.Name()).ToCString()); | 554 String::Handle(cls.Name()).ToCString()); |
561 } | 555 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 } | 641 } |
648 } | 642 } |
649 | 643 |
650 | 644 |
651 // Expand the type arguments of the given type and finalize its full type | 645 // Expand the type arguments of the given type and finalize its full type |
652 // argument vector. Return the number of type arguments (0 for a raw type). | 646 // argument vector. Return the number of type arguments (0 for a raw type). |
653 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( | 647 intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments( |
654 const Class& cls, | 648 const Class& cls, |
655 const AbstractType& type, | 649 const AbstractType& type, |
656 PendingTypes* pending_types) { | 650 PendingTypes* pending_types) { |
657 Zone* Z = Thread::Current()->zone(); | 651 Zone* zone = Thread::Current()->zone(); |
658 // The type class does not need to be finalized in order to finalize the type, | 652 // The type class does not need to be finalized in order to finalize the type, |
659 // however, it must at least be resolved (this was done as part of resolving | 653 // however, it must at least be resolved (this was done as part of resolving |
660 // the type itself, a precondition to calling FinalizeType). | 654 // the type itself, a precondition to calling FinalizeType). |
661 // Also, the interfaces of the type class must be resolved and the type | 655 // Also, the interfaces of the type class must be resolved and the type |
662 // parameters of the type class must be finalized. | 656 // parameters of the type class must be finalized. |
663 Class& type_class = Class::Handle(Z, type.type_class()); | 657 Class& type_class = Class::Handle(zone, type.type_class()); |
664 if (!type_class.is_type_finalized()) { | 658 if (!type_class.is_type_finalized()) { |
665 FinalizeTypeParameters(type_class, pending_types); | 659 FinalizeTypeParameters(type_class, pending_types); |
666 ResolveUpperBounds(type_class); | 660 ResolveUpperBounds(type_class); |
667 } | 661 } |
668 | 662 |
669 // The finalized type argument vector needs num_type_arguments types. | 663 // The finalized type argument vector needs num_type_arguments types. |
670 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 664 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
671 // The class has num_type_parameters type parameters. | 665 // The class has num_type_parameters type parameters. |
672 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 666 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
673 | 667 |
674 // If we are not reifying types, drop type arguments. | 668 // If we are not reifying types, drop type arguments. |
675 if (!FLAG_reify) { | 669 if (!FLAG_reify) { |
676 type.set_arguments(TypeArguments::Handle(Z, TypeArguments::null())); | 670 type.set_arguments(TypeArguments::Handle(zone, TypeArguments::null())); |
677 } | 671 } |
678 | 672 |
679 // Initialize the type argument vector. | 673 // Initialize the type argument vector. |
680 // Check the number of parsed type arguments, if any. | 674 // Check the number of parsed type arguments, if any. |
681 // Specifying no type arguments indicates a raw type, which is not an error. | 675 // Specifying no type arguments indicates a raw type, which is not an error. |
682 // However, type parameter bounds are checked below, even for a raw type. | 676 // However, type parameter bounds are checked below, even for a raw type. |
683 TypeArguments& arguments = TypeArguments::Handle(Z, type.arguments()); | 677 TypeArguments& arguments = TypeArguments::Handle(zone, type.arguments()); |
684 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 678 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
685 // Wrong number of type arguments. The type is mapped to the raw type. | 679 // Wrong number of type arguments. The type is mapped to the raw type. |
686 if (Isolate::Current()->error_on_bad_type()) { | 680 if (Isolate::Current()->error_on_bad_type()) { |
687 const String& type_class_name = String::Handle(Z, type_class.Name()); | 681 const String& type_class_name = String::Handle(zone, type_class.Name()); |
688 ReportError(cls, type.token_pos(), | 682 ReportError(cls, type.token_pos(), |
689 "wrong number of type arguments for class '%s'", | 683 "wrong number of type arguments for class '%s'", |
690 type_class_name.ToCString()); | 684 type_class_name.ToCString()); |
691 } | 685 } |
692 // Make the type raw and continue without reporting any error. | 686 // Make the type raw and continue without reporting any error. |
693 // A static warning should have been reported. | 687 // A static warning should have been reported. |
694 arguments = TypeArguments::null(); | 688 arguments = TypeArguments::null(); |
695 type.set_arguments(arguments); | 689 type.set_arguments(arguments); |
696 } | 690 } |
697 | 691 |
698 // Mark the type as being finalized in order to detect self reference and | 692 // Mark the type as being finalized in order to detect self reference and |
699 // postpone bound checking until after all types in the graph of | 693 // postpone bound checking until after all types in the graph of |
700 // mutually recursive types are finalized. | 694 // mutually recursive types are finalized. |
701 type.SetIsBeingFinalized(); | 695 type.SetIsBeingFinalized(); |
702 pending_types->Add(type); | 696 pending_types->Add(type); |
703 | 697 |
704 // The full type argument vector consists of the type arguments of the | 698 // The full type argument vector consists of the type arguments of the |
705 // super types of type_class, which are initialized from the parsed | 699 // super types of type_class, which are initialized from the parsed |
706 // type arguments, followed by the parsed type arguments. | 700 // type arguments, followed by the parsed type arguments. |
707 TypeArguments& full_arguments = TypeArguments::Handle(Z); | 701 TypeArguments& full_arguments = TypeArguments::Handle(zone); |
708 if (FLAG_reify && (num_type_arguments > 0)) { | 702 if (FLAG_reify && (num_type_arguments > 0)) { |
709 // If no type arguments were parsed and if the super types do not prepend | 703 // If no type arguments were parsed and if the super types do not prepend |
710 // type arguments to the vector, we can leave the vector as null. | 704 // type arguments to the vector, we can leave the vector as null. |
711 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 705 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
712 full_arguments = TypeArguments::New(num_type_arguments); | 706 full_arguments = TypeArguments::New(num_type_arguments); |
713 // Copy the parsed type arguments at the correct offset in the full type | 707 // Copy the parsed type arguments at the correct offset in the full type |
714 // argument vector. | 708 // argument vector. |
715 const intptr_t offset = num_type_arguments - num_type_parameters; | 709 const intptr_t offset = num_type_arguments - num_type_parameters; |
716 AbstractType& type_arg = | 710 AbstractType& type_arg = |
717 AbstractType::Handle(Z, Type::DynamicType()); | 711 AbstractType::Handle(zone, Type::DynamicType()); |
718 // Leave the temporary type arguments at indices [0..offset[ as null. | 712 // Leave the temporary type arguments at indices [0..offset[ as null. |
719 for (intptr_t i = 0; i < num_type_parameters; i++) { | 713 for (intptr_t i = 0; i < num_type_parameters; i++) { |
720 // If no type parameters were provided, a raw type is desired, so we | 714 // If no type parameters were provided, a raw type is desired, so we |
721 // create a vector of dynamic. | 715 // create a vector of dynamic. |
722 if (!arguments.IsNull()) { | 716 if (!arguments.IsNull()) { |
723 type_arg = arguments.TypeAt(i); | 717 type_arg = arguments.TypeAt(i); |
724 // The parsed type_arg may or may not be finalized. | 718 // The parsed type_arg may or may not be finalized. |
725 } | 719 } |
726 full_arguments.SetTypeAt(offset + i, type_arg); | 720 full_arguments.SetTypeAt(offset + i, type_arg); |
727 } | 721 } |
(...skipping 11 matching lines...) Expand all Loading... |
739 ASSERT(!type_arg.IsBeingFinalized()); | 733 ASSERT(!type_arg.IsBeingFinalized()); |
740 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); | 734 type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types); |
741 if (type_arg.IsMalformed()) { | 735 if (type_arg.IsMalformed()) { |
742 // Malformed type arguments are mapped to dynamic. | 736 // Malformed type arguments are mapped to dynamic. |
743 type_arg = Type::DynamicType(); | 737 type_arg = Type::DynamicType(); |
744 } | 738 } |
745 full_arguments.SetTypeAt(offset + i, type_arg); | 739 full_arguments.SetTypeAt(offset + i, type_arg); |
746 } | 740 } |
747 } | 741 } |
748 if (offset > 0) { | 742 if (offset > 0) { |
749 TrailPtr instantiation_trail = new Trail(Z, 4); | 743 TrailPtr instantiation_trail = new Trail(zone, 4); |
750 Error& bound_error = Error::Handle(Z); | 744 Error& bound_error = Error::Handle(zone); |
751 FinalizeTypeArguments(type_class, full_arguments, offset, | 745 FinalizeTypeArguments(type_class, full_arguments, offset, |
752 &bound_error, pending_types, instantiation_trail); | 746 &bound_error, pending_types, instantiation_trail); |
753 } | 747 } |
754 if (full_arguments.IsRaw(0, num_type_arguments)) { | 748 if (full_arguments.IsRaw(0, num_type_arguments)) { |
755 // The parameterized_type is raw. Set its argument vector to null, which | 749 // The parameterized_type is raw. Set its argument vector to null, which |
756 // is more efficient in type tests. | 750 // is more efficient in type tests. |
757 full_arguments = TypeArguments::null(); | 751 full_arguments = TypeArguments::null(); |
758 } | 752 } |
759 type.set_arguments(full_arguments); | 753 type.set_arguments(full_arguments); |
760 } else { | 754 } else { |
761 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. | 755 ASSERT(full_arguments.IsNull()); // Use null vector for raw type. |
762 } | 756 } |
763 } | 757 } |
764 | 758 |
765 // Self referencing types may get finalized indirectly. | 759 // Self referencing types may get finalized indirectly. |
766 if (!type.IsFinalized()) { | 760 if (!type.IsFinalized()) { |
767 ASSERT(full_arguments.IsNull() || | 761 ASSERT(full_arguments.IsNull() || |
768 !full_arguments.IsRaw(0, num_type_arguments)); | 762 !full_arguments.IsRaw(0, num_type_arguments)); |
769 if (FLAG_trace_type_finalization) { | 763 if (FLAG_trace_type_finalization) { |
770 THR_Print("Marking type '%s' as finalized for class '%s'\n", | 764 THR_Print("Marking type '%s' as finalized for class '%s'\n", |
771 String::Handle(Z, type.Name()).ToCString(), | 765 String::Handle(zone, type.Name()).ToCString(), |
772 String::Handle(Z, cls.Name()).ToCString()); | 766 String::Handle(zone, cls.Name()).ToCString()); |
773 } | 767 } |
774 // Mark the type as finalized. | 768 // Mark the type as finalized. |
775 type.SetIsFinalized(); | 769 type.SetIsFinalized(); |
776 // Do not yet remove the type from the pending_types array. | 770 // Do not yet remove the type from the pending_types array. |
777 } | 771 } |
778 return full_arguments.IsNull() ? 0 : full_arguments.Length(); | 772 return full_arguments.IsNull() ? 0 : full_arguments.Length(); |
779 } | 773 } |
780 | 774 |
781 | 775 |
782 // Finalize the type argument vector 'arguments' of the type defined by the | 776 // Finalize the type argument vector 'arguments' of the type defined by the |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 TypeArguments& super_type_args = TypeArguments::Handle( | 833 TypeArguments& super_type_args = TypeArguments::Handle( |
840 super_type.arguments()); | 834 super_type.arguments()); |
841 // Offset of super type's type parameters in cls' type argument vector. | 835 // Offset of super type's type parameters in cls' type argument vector. |
842 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 836 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
843 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 837 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
844 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 838 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
845 if (!super_type_args.IsNull()) { | 839 if (!super_type_args.IsNull()) { |
846 super_type_arg = super_type_args.TypeAt(i); | 840 super_type_arg = super_type_args.TypeAt(i); |
847 if (!super_type_arg.IsTypeRef()) { | 841 if (!super_type_arg.IsTypeRef()) { |
848 if (super_type_arg.IsBeingFinalized()) { | 842 if (super_type_arg.IsBeingFinalized()) { |
849 ASSERT(super_type_arg.IsType() || super_type_arg.IsFunctionType()); | 843 ASSERT(super_type_arg.IsType()); |
850 CheckRecursiveType(cls, super_type_arg, pending_types); | 844 CheckRecursiveType(cls, super_type_arg, pending_types); |
851 if (FLAG_trace_type_finalization) { | 845 if (FLAG_trace_type_finalization) { |
852 THR_Print("Creating TypeRef '%s': '%s'\n", | 846 THR_Print("Creating TypeRef '%s': '%s'\n", |
853 String::Handle(super_type_arg.Name()).ToCString(), | 847 String::Handle(super_type_arg.Name()).ToCString(), |
854 super_type_arg.ToCString()); | 848 super_type_arg.ToCString()); |
855 } | 849 } |
856 super_type_arg = TypeRef::New(super_type_arg); | 850 super_type_arg = TypeRef::New(super_type_arg); |
857 super_type_args.SetTypeAt(i, super_type_arg); | 851 super_type_args.SetTypeAt(i, super_type_arg); |
858 } else { | 852 } else { |
859 if (!super_type_arg.IsFinalized()) { | 853 if (!super_type_arg.IsFinalized()) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 if (error.IsNull() && | 992 if (error.IsNull() && |
999 !(type_arg.Equals(type_param) && | 993 !(type_arg.Equals(type_param) && |
1000 instantiated_bound.Equals(declared_bound))) { | 994 instantiated_bound.Equals(declared_bound))) { |
1001 // If type_arg is a type parameter, its declared bound may not be | 995 // If type_arg is a type parameter, its declared bound may not be |
1002 // resolved yet. | 996 // resolved yet. |
1003 if (type_arg.IsTypeParameter()) { | 997 if (type_arg.IsTypeParameter()) { |
1004 const Class& type_arg_cls = Class::Handle( | 998 const Class& type_arg_cls = Class::Handle( |
1005 TypeParameter::Cast(type_arg).parameterized_class()); | 999 TypeParameter::Cast(type_arg).parameterized_class()); |
1006 AbstractType& bound = AbstractType::Handle( | 1000 AbstractType& bound = AbstractType::Handle( |
1007 TypeParameter::Cast(type_arg).bound()); | 1001 TypeParameter::Cast(type_arg).bound()); |
1008 bound = ResolveType(type_arg_cls, bound); | 1002 ResolveType(type_arg_cls, bound); |
1009 TypeParameter::Cast(type_arg).set_bound(bound); | |
1010 } | 1003 } |
1011 // This may be called only if type needs to be finalized, therefore | 1004 // This may be called only if type needs to be finalized, therefore |
1012 // seems OK to allocate finalized types in old space. | 1005 // seems OK to allocate finalized types in old space. |
1013 if (!type_param.CheckBound(type_arg, instantiated_bound, | 1006 if (!type_param.CheckBound(type_arg, instantiated_bound, |
1014 &error, NULL, Heap::kOld) && | 1007 &error, NULL, Heap::kOld) && |
1015 error.IsNull()) { | 1008 error.IsNull()) { |
1016 // The bound cannot be checked at compile time; postpone to run time. | 1009 // The bound cannot be checked at compile time; postpone to run time. |
1017 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 1010 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
1018 arguments.SetTypeAt(offset + i, type_arg); | 1011 arguments.SetTypeAt(offset + i, type_arg); |
1019 } | 1012 } |
1020 } | 1013 } |
1021 if (!error.IsNull() && bound_error->IsNull()) { | 1014 if (!error.IsNull() && bound_error->IsNull()) { |
1022 *bound_error = error.raw(); | 1015 *bound_error = error.raw(); |
1023 } | 1016 } |
1024 } | 1017 } |
1025 } | 1018 } |
1026 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 1019 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
1027 if (!super_type.IsNull()) { | 1020 if (!super_type.IsNull()) { |
1028 const Class& super_class = Class::Handle(super_type.type_class()); | 1021 const Class& super_class = Class::Handle(super_type.type_class()); |
1029 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 1022 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
1030 } | 1023 } |
1031 } | 1024 } |
1032 | 1025 |
1033 | 1026 |
1034 void ClassFinalizer::CheckTypeBounds(const Class& cls, | 1027 void ClassFinalizer::CheckTypeBounds(const Class& cls, |
1035 const AbstractType& type) { | 1028 const AbstractType& type) { |
1036 Zone* Z = Thread::Current()->zone(); | 1029 Zone* zone = Thread::Current()->zone(); |
1037 ASSERT(type.IsType() || type.IsFunctionType()); | 1030 ASSERT(type.IsType()); |
1038 ASSERT(type.IsFinalized()); | 1031 ASSERT(type.IsFinalized()); |
1039 ASSERT(!type.IsCanonical()); | 1032 ASSERT(!type.IsCanonical()); |
1040 TypeArguments& arguments = TypeArguments::Handle(Z, type.arguments()); | 1033 TypeArguments& arguments = TypeArguments::Handle(zone, type.arguments()); |
1041 if (arguments.IsNull()) { | 1034 if (arguments.IsNull()) { |
1042 return; | 1035 return; |
1043 } | 1036 } |
1044 if (FLAG_trace_type_finalization) { | 1037 if (FLAG_trace_type_finalization) { |
1045 THR_Print("Checking bounds of type '%s' for class '%s'\n", | 1038 THR_Print("Checking bounds of type '%s' for class '%s'\n", |
1046 String::Handle(Z, type.Name()).ToCString(), | 1039 String::Handle(zone, type.Name()).ToCString(), |
1047 String::Handle(Z, cls.Name()).ToCString()); | 1040 String::Handle(zone, cls.Name()).ToCString()); |
1048 } | 1041 } |
1049 const Class& type_class = Class::Handle(Z, type.type_class()); | 1042 const Class& type_class = Class::Handle(zone, type.type_class()); |
1050 Error& bound_error = Error::Handle(Z); | 1043 Error& bound_error = Error::Handle(zone); |
1051 CheckTypeArgumentBounds(type_class, arguments, &bound_error); | 1044 CheckTypeArgumentBounds(type_class, arguments, &bound_error); |
1052 // CheckTypeArgumentBounds may have indirectly canonicalized this type. | 1045 // CheckTypeArgumentBounds may have indirectly canonicalized this type. |
1053 if (!type.IsCanonical()) { | 1046 if (!type.IsCanonical()) { |
1054 type.set_arguments(arguments); | 1047 type.set_arguments(arguments); |
1055 // If a bound error occurred, mark the type as malbounded. | 1048 // If a bound error occurred, mark the type as malbounded. |
1056 // The bound error will be ignored in production mode. | 1049 // The bound error will be ignored in production mode. |
1057 if (!bound_error.IsNull()) { | 1050 if (!bound_error.IsNull()) { |
1058 // No compile-time error during finalization. | 1051 // No compile-time error during finalization. |
1059 const String& type_name = String::Handle(Z, type.UserVisibleName()); | 1052 const String& type_name = String::Handle(zone, type.UserVisibleName()); |
1060 FinalizeMalboundedType(bound_error, | 1053 FinalizeMalboundedType(bound_error, |
1061 Script::Handle(Z, cls.script()), | 1054 Script::Handle(zone, cls.script()), |
1062 type, | 1055 type, |
1063 "type '%s' has an out of bound type argument", | 1056 "type '%s' has an out of bound type argument", |
1064 type_name.ToCString()); | 1057 type_name.ToCString()); |
1065 if (FLAG_trace_type_finalization) { | 1058 if (FLAG_trace_type_finalization) { |
1066 THR_Print("Marking type '%s' as malbounded: %s\n", | 1059 THR_Print("Marking type '%s' as malbounded: %s\n", |
1067 String::Handle(Z, type.Name()).ToCString(), | 1060 String::Handle(zone, type.Name()).ToCString(), |
1068 bound_error.ToErrorCString()); | 1061 bound_error.ToErrorCString()); |
1069 } | 1062 } |
1070 } | 1063 } |
1071 } | 1064 } |
1072 if (FLAG_trace_type_finalization) { | 1065 if (FLAG_trace_type_finalization) { |
1073 THR_Print("Done checking bounds of type '%s': %s\n", | 1066 THR_Print("Done checking bounds of type '%s': %s\n", |
1074 String::Handle(Z, type.Name()).ToCString(), | 1067 String::Handle(zone, type.Name()).ToCString(), |
1075 type.ToCString()); | 1068 type.ToCString()); |
1076 } | 1069 } |
1077 } | 1070 } |
1078 | 1071 |
1079 | 1072 |
1080 RawAbstractType* ClassFinalizer::FinalizeType( | 1073 RawAbstractType* ClassFinalizer::FinalizeType( |
1081 const Class& cls, | 1074 const Class& cls, |
1082 const AbstractType& type, | 1075 const AbstractType& type, |
1083 FinalizationKind finalization, | 1076 FinalizationKind finalization, |
1084 PendingTypes* pending_types) { | 1077 PendingTypes* pending_types) { |
1085 // Only the 'root' type of the graph can be canonicalized, after all depending | 1078 // Only the 'root' type of the graph can be canonicalized, after all depending |
1086 // types have been bound checked. | 1079 // types have been bound checked. |
1087 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); | 1080 ASSERT((pending_types == NULL) || (finalization < kCanonicalize)); |
1088 if (type.IsFinalized()) { | 1081 if (type.IsFinalized()) { |
1089 // Ensure type is canonical if canonicalization is requested, unless type is | 1082 // Ensure type is canonical if canonicalization is requested, unless type is |
1090 // malformed. | 1083 // malformed. |
1091 if ((finalization >= kCanonicalize) && | 1084 if ((finalization >= kCanonicalize) && |
1092 !type.IsMalformed() && | 1085 !type.IsMalformed() && |
1093 !type.IsCanonical() && | 1086 !type.IsCanonical() && |
1094 (type.IsType() || type.IsFunctionType())) { | 1087 type.IsType()) { |
1095 CheckTypeBounds(cls, type); | 1088 CheckTypeBounds(cls, type); |
1096 return type.Canonicalize(); | 1089 return type.Canonicalize(); |
1097 } | 1090 } |
1098 return type.raw(); | 1091 return type.raw(); |
1099 } | 1092 } |
1100 ASSERT(finalization >= kFinalize); | 1093 ASSERT(finalization >= kFinalize); |
1101 | 1094 |
1102 if (type.IsTypeRef()) { | 1095 if (type.IsTypeRef()) { |
1103 // The referenced type will be finalized later by the code that set the | 1096 // The referenced type will be finalized later by the code that set the |
1104 // is_being_finalized mark bit. | 1097 // is_being_finalized mark bit. |
1105 return type.raw(); | 1098 return type.raw(); |
1106 } | 1099 } |
1107 | 1100 |
1108 // Recursive types must be processed in FinalizeTypeArguments() and cannot be | 1101 // Recursive types must be processed in FinalizeTypeArguments() and cannot be |
1109 // encountered here. | 1102 // encountered here. |
1110 ASSERT(!type.IsBeingFinalized()); | 1103 ASSERT(!type.IsBeingFinalized()); |
1111 | 1104 |
1112 Zone* Z = Thread::Current()->zone(); | 1105 Zone* zone = Thread::Current()->zone(); |
1113 const AbstractType& resolved_type = | 1106 ResolveType(cls, type); |
1114 AbstractType::Handle(Z, ResolveType(cls, type)); | |
1115 // A malformed type gets mapped to a finalized type. | 1107 // A malformed type gets mapped to a finalized type. |
1116 if (resolved_type.IsMalformed()) { | 1108 if (type.IsMalformed()) { |
1117 ASSERT(resolved_type.IsFinalized()); | 1109 ASSERT(type.IsFinalized()); |
1118 return resolved_type.raw(); | 1110 return type.raw(); |
1119 } | 1111 } |
1120 | 1112 |
1121 if (FLAG_trace_type_finalization) { | 1113 if (FLAG_trace_type_finalization) { |
1122 THR_Print("Finalizing type '%s' for class '%s'\n", | 1114 THR_Print("Finalizing type '%s' for class '%s'\n", |
1123 String::Handle(Z, resolved_type.Name()).ToCString(), | 1115 String::Handle(zone, type.Name()).ToCString(), |
1124 String::Handle(Z, cls.Name()).ToCString()); | 1116 String::Handle(zone, cls.Name()).ToCString()); |
1125 } | 1117 } |
1126 | 1118 |
1127 if (resolved_type.IsTypeParameter()) { | 1119 if (type.IsTypeParameter()) { |
1128 const TypeParameter& type_parameter = TypeParameter::Cast(resolved_type); | 1120 const TypeParameter& type_parameter = TypeParameter::Cast(type); |
1129 const Class& parameterized_class = | 1121 const Class& parameterized_class = |
1130 Class::Handle(Z, type_parameter.parameterized_class()); | 1122 Class::Handle(zone, type_parameter.parameterized_class()); |
1131 ASSERT(!parameterized_class.IsNull()); | 1123 ASSERT(!parameterized_class.IsNull()); |
1132 // The index must reflect the position of this type parameter in the type | 1124 // The index must reflect the position of this type parameter in the type |
1133 // arguments vector of its parameterized class. The offset to add is the | 1125 // arguments vector of its parameterized class. The offset to add is the |
1134 // number of type arguments in the super type, which is equal to the | 1126 // number of type arguments in the super type, which is equal to the |
1135 // difference in number of type arguments and type parameters of the | 1127 // difference in number of type arguments and type parameters of the |
1136 // parameterized class. | 1128 // parameterized class. |
1137 const intptr_t offset = parameterized_class.NumTypeArguments() - | 1129 const intptr_t offset = parameterized_class.NumTypeArguments() - |
1138 parameterized_class.NumTypeParameters(); | 1130 parameterized_class.NumTypeParameters(); |
1139 // Calling NumTypeParameters() may finalize this type parameter if it | 1131 // Calling NumTypeParameters() may finalize this type parameter if it |
1140 // belongs to a mixin application class. | 1132 // belongs to a mixin application class. |
1141 if (!type_parameter.IsFinalized()) { | 1133 if (!type_parameter.IsFinalized()) { |
1142 type_parameter.set_index(type_parameter.index() + offset); | 1134 type_parameter.set_index(type_parameter.index() + offset); |
1143 type_parameter.SetIsFinalized(); | 1135 type_parameter.SetIsFinalized(); |
1144 } else { | 1136 } else { |
1145 ASSERT(cls.IsMixinApplication()); | 1137 ASSERT(cls.IsMixinApplication()); |
1146 } | 1138 } |
1147 | 1139 |
1148 if (FLAG_trace_type_finalization) { | 1140 if (FLAG_trace_type_finalization) { |
1149 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", | 1141 THR_Print("Done finalizing type parameter '%s' with index %" Pd "\n", |
1150 String::Handle(Z, type_parameter.name()).ToCString(), | 1142 String::Handle(zone, type_parameter.name()).ToCString(), |
1151 type_parameter.index()); | 1143 type_parameter.index()); |
1152 } | 1144 } |
1153 | 1145 |
1154 // We do not canonicalize type parameters. | 1146 // We do not canonicalize type parameters. |
1155 return type_parameter.raw(); | 1147 return type_parameter.raw(); |
1156 } | 1148 } |
1157 | 1149 |
1158 // At this point, we can only have a Type or a FunctionType. | 1150 // At this point, we can only have a Type. |
1159 ASSERT(resolved_type.IsType() || resolved_type.IsFunctionType()); | 1151 ASSERT(type.IsType()); |
1160 | 1152 |
1161 // This type is the root type of the type graph if no pending types queue is | 1153 // This type is the root type of the type graph if no pending types queue is |
1162 // allocated yet. | 1154 // allocated yet. |
1163 const bool is_root_type = (pending_types == NULL); | 1155 const bool is_root_type = (pending_types == NULL); |
1164 if (is_root_type) { | 1156 if (is_root_type) { |
1165 pending_types = new PendingTypes(Z, 4); | 1157 pending_types = new PendingTypes(zone, 4); |
1166 } | 1158 } |
1167 | 1159 |
1168 const intptr_t num_expanded_type_arguments = | 1160 const intptr_t num_expanded_type_arguments = |
1169 ExpandAndFinalizeTypeArguments(cls, resolved_type, pending_types); | 1161 ExpandAndFinalizeTypeArguments(cls, type, pending_types); |
1170 | 1162 |
1171 // If we are done finalizing a graph of mutually recursive types, check their | 1163 // If we are done finalizing a graph of mutually recursive types, check their |
1172 // bounds. | 1164 // bounds. |
1173 if (is_root_type) { | 1165 if (is_root_type) { |
1174 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { | 1166 for (intptr_t i = pending_types->length() - 1; i >= 0; i--) { |
1175 const AbstractType& type = pending_types->At(i); | 1167 const AbstractType& type = pending_types->At(i); |
1176 if (!type.IsMalformed() && !type.IsCanonical()) { | 1168 if (!type.IsMalformed() && !type.IsCanonical()) { |
1177 CheckTypeBounds(cls, type); | 1169 CheckTypeBounds(cls, type); |
1178 } | 1170 } |
1179 } | 1171 } |
1180 } | 1172 } |
1181 | 1173 |
1182 // If the type is a FunctionType, we also need to finalize the types in its | 1174 // If the type is a function type, we also need to finalize the types in its |
1183 // signature, i.e. finalize the result type and parameter types of the | 1175 // signature, i.e. finalize the result type and parameter types of the |
1184 // signature function of this function type. | 1176 // signature function of this function type. |
1185 // We do this after marking this type as finalized in order to allow a | 1177 // We do this after marking this type as finalized in order to allow a |
1186 // function type to refer to itself via its parameter types and result type. | 1178 // function type to refer to itself via its parameter types and result type. |
1187 // Note that we do not instantiate these types according to the type | 1179 // Note that we do not instantiate these types according to the type |
1188 // arguments. This will happen on demand when executing a type test. | 1180 // arguments. This will happen on demand when executing a type test. |
1189 if (resolved_type.IsFunctionType()) { | 1181 if (type.IsFunctionType()) { |
1190 const Function& signature = | 1182 const Function& signature = |
1191 Function::Handle(Z, FunctionType::Cast(resolved_type).signature()); | 1183 Function::Handle(zone, Type::Cast(type).signature()); |
1192 const Class& scope_class = | 1184 const Class& scope_class = |
1193 Class::Handle(Z, FunctionType::Cast(resolved_type).scope_class()); | 1185 Class::Handle(zone, Type::Cast(type).type_class()); |
1194 if (scope_class.IsTypedefClass()) { | 1186 if (scope_class.IsTypedefClass()) { |
1195 FinalizeSignature(scope_class, signature); | 1187 FinalizeSignature(scope_class, signature); |
1196 } else { | 1188 } else { |
1197 FinalizeSignature(cls, signature); | 1189 FinalizeSignature(cls, signature); |
1198 } | 1190 } |
1199 } | 1191 } |
1200 | 1192 |
1201 if (FLAG_trace_type_finalization) { | 1193 if (FLAG_trace_type_finalization) { |
1202 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 1194 THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
1203 String::Handle(Z, resolved_type.Name()).ToCString(), | 1195 String::Handle(zone, type.Name()).ToCString(), |
1204 num_expanded_type_arguments, | 1196 num_expanded_type_arguments, |
1205 resolved_type.ToCString()); | 1197 type.ToCString()); |
1206 } | 1198 } |
1207 | 1199 |
1208 if (finalization >= kCanonicalize) { | 1200 if (finalization >= kCanonicalize) { |
1209 if (FLAG_trace_type_finalization) { | 1201 if (FLAG_trace_type_finalization) { |
1210 THR_Print("Canonicalizing type '%s'\n", | 1202 THR_Print("Canonicalizing type '%s'\n", |
1211 String::Handle(Z, resolved_type.Name()).ToCString()); | 1203 String::Handle(zone, type.Name()).ToCString()); |
1212 AbstractType& canonical_type = | 1204 AbstractType& canonical_type = |
1213 AbstractType::Handle(Z, resolved_type.Canonicalize()); | 1205 AbstractType::Handle(zone, type.Canonicalize()); |
1214 THR_Print("Done canonicalizing type '%s'\n", | 1206 THR_Print("Done canonicalizing type '%s'\n", |
1215 String::Handle(Z, canonical_type.Name()).ToCString()); | 1207 String::Handle(zone, canonical_type.Name()).ToCString()); |
1216 return canonical_type.raw(); | 1208 return canonical_type.raw(); |
1217 } | 1209 } |
1218 return resolved_type.Canonicalize(); | 1210 return type.Canonicalize(); |
1219 } else { | 1211 } else { |
1220 return resolved_type.raw(); | 1212 return type.raw(); |
1221 } | 1213 } |
1222 } | 1214 } |
1223 | 1215 |
1224 | 1216 |
1225 void ClassFinalizer::ResolveSignature(const Class& cls, | 1217 void ClassFinalizer::ResolveSignature(const Class& cls, |
1226 const Function& function) { | 1218 const Function& function) { |
1227 // Resolve result type. | 1219 // Resolve result type. |
1228 AbstractType& type = AbstractType::Handle(function.result_type()); | 1220 AbstractType& type = AbstractType::Handle(function.result_type()); |
1229 // It is not a compile time error if this name does not resolve to a class or | 1221 // It is not a compile time error if this name does not resolve to a class or |
1230 // interface. | 1222 // interface. |
1231 AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type)); | 1223 ResolveType(cls, type); |
1232 if (resolved_type.raw() != type.raw()) { | |
1233 function.set_result_type(resolved_type); | |
1234 } | |
1235 // Resolve formal parameter types. | 1224 // Resolve formal parameter types. |
1236 const intptr_t num_parameters = function.NumParameters(); | 1225 const intptr_t num_parameters = function.NumParameters(); |
1237 for (intptr_t i = 0; i < num_parameters; i++) { | 1226 for (intptr_t i = 0; i < num_parameters; i++) { |
1238 type = function.ParameterTypeAt(i); | 1227 type = function.ParameterTypeAt(i); |
1239 resolved_type = ResolveType(cls, type); | 1228 ResolveType(cls, type); |
1240 if (resolved_type.raw() != type.raw()) { | |
1241 function.SetParameterTypeAt(i, resolved_type); | |
1242 } | |
1243 } | 1229 } |
1244 } | 1230 } |
1245 | 1231 |
1246 | 1232 |
1247 void ClassFinalizer::FinalizeSignature(const Class& cls, | 1233 void ClassFinalizer::FinalizeSignature(const Class& cls, |
1248 const Function& function) { | 1234 const Function& function) { |
1249 // Finalize result type. | 1235 // Finalize result type. |
1250 AbstractType& type = AbstractType::Handle(function.result_type()); | 1236 AbstractType& type = AbstractType::Handle(function.result_type()); |
1251 // It is not a compile time error if this name does not resolve to a class or | 1237 // It is not a compile time error if this name does not resolve to a class or |
1252 // interface. | 1238 // interface. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 AbstractType& bound = AbstractType::Handle(); | 1309 AbstractType& bound = AbstractType::Handle(); |
1324 const TypeArguments& type_params = | 1310 const TypeArguments& type_params = |
1325 TypeArguments::Handle(cls.type_parameters()); | 1311 TypeArguments::Handle(cls.type_parameters()); |
1326 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1312 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
1327 (type_params.Length() == num_type_params)); | 1313 (type_params.Length() == num_type_params)); |
1328 // In a first pass, resolve all bounds. This guarantees that finalization | 1314 // In a first pass, resolve all bounds. This guarantees that finalization |
1329 // of mutually referencing bounds will not encounter an unresolved bound. | 1315 // of mutually referencing bounds will not encounter an unresolved bound. |
1330 for (intptr_t i = 0; i < num_type_params; i++) { | 1316 for (intptr_t i = 0; i < num_type_params; i++) { |
1331 type_param ^= type_params.TypeAt(i); | 1317 type_param ^= type_params.TypeAt(i); |
1332 bound = type_param.bound(); | 1318 bound = type_param.bound(); |
1333 bound = ResolveType(cls, bound); | 1319 ResolveType(cls, bound); |
1334 type_param.set_bound(bound); | |
1335 } | 1320 } |
1336 } | 1321 } |
1337 | 1322 |
1338 | 1323 |
1339 // Finalize the upper bounds of the type parameters of class cls. | 1324 // Finalize the upper bounds of the type parameters of class cls. |
1340 void ClassFinalizer::FinalizeUpperBounds(const Class& cls, | 1325 void ClassFinalizer::FinalizeUpperBounds(const Class& cls, |
1341 FinalizationKind finalization) { | 1326 FinalizationKind finalization) { |
1342 const intptr_t num_type_params = cls.NumTypeParameters(); | 1327 const intptr_t num_type_params = cls.NumTypeParameters(); |
1343 TypeParameter& type_param = TypeParameter::Handle(); | 1328 TypeParameter& type_param = TypeParameter::Handle(); |
1344 AbstractType& bound = AbstractType::Handle(); | 1329 AbstractType& bound = AbstractType::Handle(); |
(...skipping 30 matching lines...) Expand all Loading... |
1375 // conflict with an accessible static setter 'v=' of a super class). | 1360 // conflict with an accessible static setter 'v=' of a super class). |
1376 // The compile-time errors we report are: | 1361 // The compile-time errors we report are: |
1377 // - a static member 'v' conflicting with an inherited instance member 'v'. | 1362 // - a static member 'v' conflicting with an inherited instance member 'v'. |
1378 // - a static setter 'v=' conflicting with an inherited instance setter 'v='. | 1363 // - a static setter 'v=' conflicting with an inherited instance setter 'v='. |
1379 // - an instance method conflicting with an inherited instance field or | 1364 // - an instance method conflicting with an inherited instance field or |
1380 // instance getter. | 1365 // instance getter. |
1381 // - an instance field or instance getter conflicting with an inherited | 1366 // - an instance field or instance getter conflicting with an inherited |
1382 // instance method. | 1367 // instance method. |
1383 | 1368 |
1384 // Resolve type of fields and check for conflicts in super classes. | 1369 // Resolve type of fields and check for conflicts in super classes. |
1385 Zone* Z = Thread::Current()->zone(); | 1370 Zone* zone = Thread::Current()->zone(); |
1386 Array& array = Array::Handle(Z, cls.fields()); | 1371 Array& array = Array::Handle(zone, cls.fields()); |
1387 Field& field = Field::Handle(Z); | 1372 Field& field = Field::Handle(zone); |
1388 AbstractType& type = AbstractType::Handle(Z); | 1373 AbstractType& type = AbstractType::Handle(zone); |
1389 String& name = String::Handle(Z); | 1374 String& name = String::Handle(zone); |
1390 String& getter_name = String::Handle(Z); | 1375 String& getter_name = String::Handle(zone); |
1391 String& setter_name = String::Handle(Z); | 1376 String& setter_name = String::Handle(zone); |
1392 Class& super_class = Class::Handle(Z); | 1377 Class& super_class = Class::Handle(zone); |
1393 const intptr_t num_fields = array.Length(); | 1378 const intptr_t num_fields = array.Length(); |
1394 for (intptr_t i = 0; i < num_fields; i++) { | 1379 for (intptr_t i = 0; i < num_fields; i++) { |
1395 field ^= array.At(i); | 1380 field ^= array.At(i); |
1396 type = field.type(); | 1381 type = field.type(); |
1397 type = FinalizeType(cls, type, kCanonicalize); | 1382 type = FinalizeType(cls, type, kCanonicalize); |
1398 field.SetFieldType(type); | 1383 field.SetFieldType(type); |
1399 name = field.name(); | 1384 name = field.name(); |
1400 if (field.is_static()) { | 1385 if (field.is_static()) { |
1401 getter_name = Field::GetterSymbol(name); | 1386 getter_name = Field::GetterSymbol(name); |
1402 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1387 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
1403 if (!super_class.IsNull()) { | 1388 if (!super_class.IsNull()) { |
1404 const String& class_name = String::Handle(Z, cls.Name()); | 1389 const String& class_name = String::Handle(zone, cls.Name()); |
1405 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1390 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1406 ReportError(cls, field.token_pos(), | 1391 ReportError(cls, field.token_pos(), |
1407 "static field '%s' of class '%s' conflicts with " | 1392 "static field '%s' of class '%s' conflicts with " |
1408 "instance member '%s' of super class '%s'", | 1393 "instance member '%s' of super class '%s'", |
1409 name.ToCString(), | 1394 name.ToCString(), |
1410 class_name.ToCString(), | 1395 class_name.ToCString(), |
1411 name.ToCString(), | 1396 name.ToCString(), |
1412 super_class_name.ToCString()); | 1397 super_cls_name.ToCString()); |
1413 } | 1398 } |
1414 // An implicit setter is not generated for a static field, therefore, we | 1399 // An implicit setter is not generated for a static field, therefore, we |
1415 // cannot rely on the code below handling the static setter case to report | 1400 // cannot rely on the code below handling the static setter case to report |
1416 // a conflict with an instance setter. So we check explicitly here. | 1401 // a conflict with an instance setter. So we check explicitly here. |
1417 setter_name = Field::SetterSymbol(name); | 1402 setter_name = Field::SetterSymbol(name); |
1418 super_class = FindSuperOwnerOfFunction(cls, setter_name); | 1403 super_class = FindSuperOwnerOfFunction(cls, setter_name); |
1419 if (!super_class.IsNull()) { | 1404 if (!super_class.IsNull()) { |
1420 const String& class_name = String::Handle(Z, cls.Name()); | 1405 const String& class_name = String::Handle(zone, cls.Name()); |
1421 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1406 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1422 ReportError(cls, field.token_pos(), | 1407 ReportError(cls, field.token_pos(), |
1423 "static field '%s' of class '%s' conflicts with " | 1408 "static field '%s' of class '%s' conflicts with " |
1424 "instance setter '%s=' of super class '%s'", | 1409 "instance setter '%s=' of super class '%s'", |
1425 name.ToCString(), | 1410 name.ToCString(), |
1426 class_name.ToCString(), | 1411 class_name.ToCString(), |
1427 name.ToCString(), | 1412 name.ToCString(), |
1428 super_class_name.ToCString()); | 1413 super_cls_name.ToCString()); |
1429 } | 1414 } |
1430 | 1415 |
1431 } else { | 1416 } else { |
1432 // Instance field. Check whether the field overrides a method | 1417 // Instance field. Check whether the field overrides a method |
1433 // (but not getter). | 1418 // (but not getter). |
1434 super_class = FindSuperOwnerOfFunction(cls, name); | 1419 super_class = FindSuperOwnerOfFunction(cls, name); |
1435 if (!super_class.IsNull()) { | 1420 if (!super_class.IsNull()) { |
1436 const String& class_name = String::Handle(Z, cls.Name()); | 1421 const String& class_name = String::Handle(zone, cls.Name()); |
1437 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1422 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1438 ReportError(cls, field.token_pos(), | 1423 ReportError(cls, field.token_pos(), |
1439 "field '%s' of class '%s' conflicts with method '%s' " | 1424 "field '%s' of class '%s' conflicts with method '%s' " |
1440 "of super class '%s'", | 1425 "of super class '%s'", |
1441 name.ToCString(), | 1426 name.ToCString(), |
1442 class_name.ToCString(), | 1427 class_name.ToCString(), |
1443 name.ToCString(), | 1428 name.ToCString(), |
1444 super_class_name.ToCString()); | 1429 super_cls_name.ToCString()); |
1445 } | 1430 } |
1446 } | 1431 } |
1447 if (field.is_static() && | 1432 if (field.is_static() && |
1448 (field.StaticValue() != Object::null()) && | 1433 (field.StaticValue() != Object::null()) && |
1449 (field.StaticValue() != Object::sentinel().raw())) { | 1434 (field.StaticValue() != Object::sentinel().raw())) { |
1450 // The parser does not preset the value if the type is a type parameter or | 1435 // The parser does not preset the value if the type is a type parameter or |
1451 // is parameterized unless the value is null. | 1436 // is parameterized unless the value is null. |
1452 Error& error = Error::Handle(Z); | 1437 Error& error = Error::Handle(zone); |
1453 if (type.IsMalformedOrMalbounded()) { | 1438 if (type.IsMalformedOrMalbounded()) { |
1454 error = type.error(); | 1439 error = type.error(); |
1455 } else { | 1440 } else { |
1456 ASSERT(type.IsInstantiated()); | 1441 ASSERT(type.IsInstantiated()); |
1457 } | 1442 } |
1458 const Instance& const_value = | 1443 const Instance& const_value = |
1459 Instance::Handle(Z, field.StaticValue()); | 1444 Instance::Handle(zone, field.StaticValue()); |
1460 if (!error.IsNull() || | 1445 if (!error.IsNull() || |
1461 (!type.IsDynamicType() && | 1446 (!type.IsDynamicType() && |
1462 !const_value.IsInstanceOf(type, | 1447 !const_value.IsInstanceOf(type, |
1463 Object::null_type_arguments(), | 1448 Object::null_type_arguments(), |
1464 &error))) { | 1449 &error))) { |
1465 if (Isolate::Current()->error_on_bad_type()) { | 1450 if (Isolate::Current()->error_on_bad_type()) { |
1466 const AbstractType& const_value_type = AbstractType::Handle( | 1451 const AbstractType& const_value_type = AbstractType::Handle( |
1467 Z, const_value.GetType()); | 1452 zone, const_value.GetType()); |
1468 const String& const_value_type_name = String::Handle( | 1453 const String& const_value_type_name = String::Handle( |
1469 Z, const_value_type.UserVisibleName()); | 1454 zone, const_value_type.UserVisibleName()); |
1470 const String& type_name = String::Handle(Z, type.UserVisibleName()); | 1455 const String& type_name = String::Handle( |
| 1456 zone, type.UserVisibleName()); |
1471 ReportErrors(error, cls, field.token_pos(), | 1457 ReportErrors(error, cls, field.token_pos(), |
1472 "error initializing static %s field '%s': " | 1458 "error initializing static %s field '%s': " |
1473 "type '%s' is not a subtype of type '%s'", | 1459 "type '%s' is not a subtype of type '%s'", |
1474 field.is_const() ? "const" : "final", | 1460 field.is_const() ? "const" : "final", |
1475 name.ToCString(), | 1461 name.ToCString(), |
1476 const_value_type_name.ToCString(), | 1462 const_value_type_name.ToCString(), |
1477 type_name.ToCString()); | 1463 type_name.ToCString()); |
1478 } else { | 1464 } else { |
1479 // Do not report an error yet, even in checked mode, since the field | 1465 // Do not report an error yet, even in checked mode, since the field |
1480 // may not actually be used. | 1466 // may not actually be used. |
1481 // Also, we may be generating a snapshot in production mode that will | 1467 // Also, we may be generating a snapshot in production mode that will |
1482 // later be executed in checked mode, in which case an error needs to | 1468 // later be executed in checked mode, in which case an error needs to |
1483 // be reported, should the field be accessed. | 1469 // be reported, should the field be accessed. |
1484 // Therefore, we undo the optimization performed by the parser, i.e. | 1470 // Therefore, we undo the optimization performed by the parser, i.e. |
1485 // we create an implicit static final getter and reset the field value | 1471 // we create an implicit static final getter and reset the field value |
1486 // to the sentinel value. | 1472 // to the sentinel value. |
1487 const Function& getter = Function::Handle( | 1473 const Function& getter = Function::Handle( |
1488 Z, | 1474 zone, |
1489 Function::New(getter_name, | 1475 Function::New(getter_name, |
1490 RawFunction::kImplicitStaticFinalGetter, | 1476 RawFunction::kImplicitStaticFinalGetter, |
1491 /* is_static = */ true, | 1477 /* is_static = */ true, |
1492 /* is_const = */ field.is_const(), | 1478 /* is_const = */ field.is_const(), |
1493 /* is_abstract = */ false, | 1479 /* is_abstract = */ false, |
1494 /* is_external = */ false, | 1480 /* is_external = */ false, |
1495 /* is_native = */ false, | 1481 /* is_native = */ false, |
1496 cls, | 1482 cls, |
1497 field.token_pos())); | 1483 field.token_pos())); |
1498 getter.set_result_type(type); | 1484 getter.set_result_type(type); |
1499 getter.set_is_debuggable(false); | 1485 getter.set_is_debuggable(false); |
1500 cls.AddFunction(getter); | 1486 cls.AddFunction(getter); |
1501 field.SetStaticValue(Object::sentinel(), true); | 1487 field.SetStaticValue(Object::sentinel(), true); |
1502 } | 1488 } |
1503 } | 1489 } |
1504 } | 1490 } |
1505 } | 1491 } |
1506 // Collect interfaces, super interfaces, and super classes of this class. | 1492 // Collect interfaces, super interfaces, and super classes of this class. |
1507 GrowableArray<const Class*> interfaces(Z, 4); | 1493 GrowableArray<const Class*> interfaces(zone, 4); |
1508 CollectInterfaces(cls, &interfaces); | 1494 CollectInterfaces(cls, &interfaces); |
1509 // Include superclasses in list of interfaces and super interfaces. | 1495 // Include superclasses in list of interfaces and super interfaces. |
1510 super_class = cls.SuperClass(); | 1496 super_class = cls.SuperClass(); |
1511 while (!super_class.IsNull()) { | 1497 while (!super_class.IsNull()) { |
1512 interfaces.Add(&Class::ZoneHandle(Z, super_class.raw())); | 1498 interfaces.Add(&Class::ZoneHandle(zone, super_class.raw())); |
1513 CollectInterfaces(super_class, &interfaces); | 1499 CollectInterfaces(super_class, &interfaces); |
1514 super_class = super_class.SuperClass(); | 1500 super_class = super_class.SuperClass(); |
1515 } | 1501 } |
1516 // Resolve function signatures and check for conflicts in super classes and | 1502 // Resolve function signatures and check for conflicts in super classes and |
1517 // interfaces. | 1503 // interfaces. |
1518 array = cls.functions(); | 1504 array = cls.functions(); |
1519 Function& function = Function::Handle(Z); | 1505 Function& function = Function::Handle(zone); |
1520 Function& overridden_function = Function::Handle(Z); | 1506 Function& overridden_function = Function::Handle(zone); |
1521 const intptr_t num_functions = array.Length(); | 1507 const intptr_t num_functions = array.Length(); |
1522 Error& error = Error::Handle(Z); | 1508 Error& error = Error::Handle(zone); |
1523 for (intptr_t i = 0; i < num_functions; i++) { | 1509 for (intptr_t i = 0; i < num_functions; i++) { |
1524 function ^= array.At(i); | 1510 function ^= array.At(i); |
1525 FinalizeSignature(cls, function); | 1511 FinalizeSignature(cls, function); |
1526 name = function.name(); | 1512 name = function.name(); |
1527 // Report signature conflicts only. | 1513 // Report signature conflicts only. |
1528 if (Isolate::Current()->error_on_bad_override() && | 1514 if (Isolate::Current()->error_on_bad_override() && |
1529 !function.is_static() && !function.IsGenerativeConstructor()) { | 1515 !function.is_static() && !function.IsGenerativeConstructor()) { |
1530 // A constructor cannot override anything. | 1516 // A constructor cannot override anything. |
1531 for (intptr_t i = 0; i < interfaces.length(); i++) { | 1517 for (intptr_t i = 0; i < interfaces.length(); i++) { |
1532 const Class* super_class = interfaces.At(i); | 1518 const Class* super_class = interfaces.At(i); |
1533 // Finalize superclass since overrides check relies on all members | 1519 // Finalize superclass since overrides check relies on all members |
1534 // of the superclass to be finalized. | 1520 // of the superclass to be finalized. |
1535 FinalizeClass(*super_class); | 1521 FinalizeClass(*super_class); |
1536 overridden_function = super_class->LookupDynamicFunction(name); | 1522 overridden_function = super_class->LookupDynamicFunction(name); |
1537 if (!overridden_function.IsNull() && | 1523 if (!overridden_function.IsNull() && |
1538 !function.HasCompatibleParametersWith(overridden_function, | 1524 !function.HasCompatibleParametersWith(overridden_function, |
1539 &error)) { | 1525 &error)) { |
1540 const String& class_name = String::Handle(Z, cls.Name()); | 1526 const String& class_name = String::Handle(zone, cls.Name()); |
1541 const String& super_class_name = | 1527 const String& super_cls_name = |
1542 String::Handle(Z, super_class->Name()); | 1528 String::Handle(zone, super_class->Name()); |
1543 ReportErrors(error, cls, function.token_pos(), | 1529 ReportErrors(error, cls, function.token_pos(), |
1544 "class '%s' overrides method '%s' of super " | 1530 "class '%s' overrides method '%s' of super " |
1545 "class '%s' with incompatible parameters", | 1531 "class '%s' with incompatible parameters", |
1546 class_name.ToCString(), | 1532 class_name.ToCString(), |
1547 name.ToCString(), | 1533 name.ToCString(), |
1548 super_class_name.ToCString()); | 1534 super_cls_name.ToCString()); |
1549 } | 1535 } |
1550 } | 1536 } |
1551 } | 1537 } |
1552 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { | 1538 if (function.IsSetterFunction() || function.IsImplicitSetterFunction()) { |
1553 if (function.is_static()) { | 1539 if (function.is_static()) { |
1554 super_class = FindSuperOwnerOfFunction(cls, name); | 1540 super_class = FindSuperOwnerOfFunction(cls, name); |
1555 if (!super_class.IsNull()) { | 1541 if (!super_class.IsNull()) { |
1556 const String& class_name = String::Handle(Z, cls.Name()); | 1542 const String& class_name = String::Handle(zone, cls.Name()); |
1557 const String& super_class_name = | 1543 const String& super_cls_name = |
1558 String::Handle(Z, super_class.Name()); | 1544 String::Handle(zone, super_class.Name()); |
1559 ReportError(cls, function.token_pos(), | 1545 ReportError(cls, function.token_pos(), |
1560 "static setter '%s=' of class '%s' conflicts with " | 1546 "static setter '%s=' of class '%s' conflicts with " |
1561 "instance setter '%s=' of super class '%s'", | 1547 "instance setter '%s=' of super class '%s'", |
1562 name.ToCString(), | 1548 name.ToCString(), |
1563 class_name.ToCString(), | 1549 class_name.ToCString(), |
1564 name.ToCString(), | 1550 name.ToCString(), |
1565 super_class_name.ToCString()); | 1551 super_cls_name.ToCString()); |
1566 } | 1552 } |
1567 } | 1553 } |
1568 continue; | 1554 continue; |
1569 } | 1555 } |
1570 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { | 1556 if (function.IsGetterFunction() || function.IsImplicitGetterFunction()) { |
1571 getter_name = name.raw(); | 1557 getter_name = name.raw(); |
1572 name = Field::NameFromGetter(getter_name); | 1558 name = Field::NameFromGetter(getter_name); |
1573 } else { | 1559 } else { |
1574 getter_name = Field::GetterSymbol(name); | 1560 getter_name = Field::GetterSymbol(name); |
1575 } | 1561 } |
1576 if (function.is_static()) { | 1562 if (function.is_static()) { |
1577 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); | 1563 super_class = FindSuperOwnerOfInstanceMember(cls, name, getter_name); |
1578 if (!super_class.IsNull()) { | 1564 if (!super_class.IsNull()) { |
1579 const String& class_name = String::Handle(Z, cls.Name()); | 1565 const String& class_name = String::Handle(zone, cls.Name()); |
1580 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1566 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1581 ReportError(cls, function.token_pos(), | 1567 ReportError(cls, function.token_pos(), |
1582 "static %s '%s' of class '%s' conflicts with " | 1568 "static %s '%s' of class '%s' conflicts with " |
1583 "instance member '%s' of super class '%s'", | 1569 "instance member '%s' of super class '%s'", |
1584 (function.IsGetterFunction() || | 1570 (function.IsGetterFunction() || |
1585 function.IsImplicitGetterFunction()) ? "getter" : "method", | 1571 function.IsImplicitGetterFunction()) ? "getter" : "method", |
1586 name.ToCString(), | 1572 name.ToCString(), |
1587 class_name.ToCString(), | 1573 class_name.ToCString(), |
1588 name.ToCString(), | 1574 name.ToCString(), |
1589 super_class_name.ToCString()); | 1575 super_cls_name.ToCString()); |
1590 } | 1576 } |
1591 if (function.IsRedirectingFactory()) { | 1577 if (function.IsRedirectingFactory()) { |
1592 // The function may be a still unresolved redirecting factory. Do not | 1578 // The function may be a still unresolved redirecting factory. Do not |
1593 // yet try to resolve it in order to avoid cycles in class finalization. | 1579 // yet try to resolve it in order to avoid cycles in class finalization. |
1594 // However, the redirection type should be finalized. | 1580 // However, the redirection type should be finalized. |
1595 // If the redirection type is from a deferred library and is not | 1581 // If the redirection type is from a deferred library and is not |
1596 // yet loaded, do not attempt to resolve. | 1582 // yet loaded, do not attempt to resolve. |
1597 Type& type = Type::Handle(Z, function.RedirectionType()); | 1583 Type& type = Type::Handle(zone, function.RedirectionType()); |
1598 if (IsLoaded(type)) { | 1584 if (IsLoaded(type)) { |
1599 type ^= FinalizeType(cls, type, kCanonicalize); | 1585 type ^= FinalizeType(cls, type, kCanonicalize); |
1600 function.SetRedirectionType(type); | 1586 function.SetRedirectionType(type); |
1601 } | 1587 } |
1602 } | 1588 } |
1603 } else if (function.IsGetterFunction() || | 1589 } else if (function.IsGetterFunction() || |
1604 function.IsImplicitGetterFunction()) { | 1590 function.IsImplicitGetterFunction()) { |
1605 super_class = FindSuperOwnerOfFunction(cls, name); | 1591 super_class = FindSuperOwnerOfFunction(cls, name); |
1606 if (!super_class.IsNull()) { | 1592 if (!super_class.IsNull()) { |
1607 const String& class_name = String::Handle(Z, cls.Name()); | 1593 const String& class_name = String::Handle(zone, cls.Name()); |
1608 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1594 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1609 ReportError(cls, function.token_pos(), | 1595 ReportError(cls, function.token_pos(), |
1610 "getter '%s' of class '%s' conflicts with " | 1596 "getter '%s' of class '%s' conflicts with " |
1611 "method '%s' of super class '%s'", | 1597 "method '%s' of super class '%s'", |
1612 name.ToCString(), | 1598 name.ToCString(), |
1613 class_name.ToCString(), | 1599 class_name.ToCString(), |
1614 name.ToCString(), | 1600 name.ToCString(), |
1615 super_class_name.ToCString()); | 1601 super_cls_name.ToCString()); |
1616 } | 1602 } |
1617 } else if (!function.IsSetterFunction() && | 1603 } else if (!function.IsSetterFunction() && |
1618 !function.IsImplicitSetterFunction()) { | 1604 !function.IsImplicitSetterFunction()) { |
1619 // A function cannot conflict with a setter, since they cannot | 1605 // A function cannot conflict with a setter, since they cannot |
1620 // have the same name. Thus, we do not need to check setters. | 1606 // have the same name. Thus, we do not need to check setters. |
1621 super_class = FindSuperOwnerOfFunction(cls, getter_name); | 1607 super_class = FindSuperOwnerOfFunction(cls, getter_name); |
1622 if (!super_class.IsNull()) { | 1608 if (!super_class.IsNull()) { |
1623 const String& class_name = String::Handle(Z, cls.Name()); | 1609 const String& class_name = String::Handle(zone, cls.Name()); |
1624 const String& super_class_name = String::Handle(Z, super_class.Name()); | 1610 const String& super_cls_name = String::Handle(zone, super_class.Name()); |
1625 ReportError(cls, function.token_pos(), | 1611 ReportError(cls, function.token_pos(), |
1626 "method '%s' of class '%s' conflicts with " | 1612 "method '%s' of class '%s' conflicts with " |
1627 "getter '%s' of super class '%s'", | 1613 "getter '%s' of super class '%s'", |
1628 name.ToCString(), | 1614 name.ToCString(), |
1629 class_name.ToCString(), | 1615 class_name.ToCString(), |
1630 name.ToCString(), | 1616 name.ToCString(), |
1631 super_class_name.ToCString()); | 1617 super_cls_name.ToCString()); |
1632 } | 1618 } |
1633 } | 1619 } |
1634 } | 1620 } |
1635 } | 1621 } |
1636 | 1622 |
1637 | 1623 |
1638 // Clone the type parameters of the super class and of the mixin class of this | 1624 // Clone the type parameters of the super class and of the mixin class of this |
1639 // mixin application class and use them as the type parameters of this mixin | 1625 // mixin application class and use them as the type parameters of this mixin |
1640 // application class. Set the type arguments of the super type, of the mixin | 1626 // application class. Set the type arguments of the super type, of the mixin |
1641 // type (as well as of the interface type, which is identical to the mixin type) | 1627 // type (as well as of the interface type, which is identical to the mixin type) |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2355 cls.set_super_type(super_type); | 2341 cls.set_super_type(super_type); |
2356 } | 2342 } |
2357 // Finalize mixin type. | 2343 // Finalize mixin type. |
2358 Type& mixin_type = Type::Handle(cls.mixin()); | 2344 Type& mixin_type = Type::Handle(cls.mixin()); |
2359 if (!mixin_type.IsNull()) { | 2345 if (!mixin_type.IsNull()) { |
2360 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); | 2346 mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed); |
2361 cls.set_mixin(mixin_type); | 2347 cls.set_mixin(mixin_type); |
2362 } | 2348 } |
2363 if (cls.IsTypedefClass()) { | 2349 if (cls.IsTypedefClass()) { |
2364 const Function& signature = Function::Handle(cls.signature_function()); | 2350 const Function& signature = Function::Handle(cls.signature_function()); |
2365 FunctionType& type = FunctionType::Handle(signature.SignatureType()); | 2351 Type& type = Type::Handle(signature.SignatureType()); |
2366 | 2352 |
2367 // Check for illegal self references. | 2353 // Check for illegal self references. |
2368 GrowableArray<intptr_t> visited_aliases; | 2354 GrowableArray<intptr_t> visited_aliases; |
2369 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { | 2355 if (!IsTypedefCycleFree(cls, type, &visited_aliases)) { |
2370 const String& name = String::Handle(cls.Name()); | 2356 const String& name = String::Handle(cls.Name()); |
2371 ReportError(cls, cls.token_pos(), | 2357 ReportError(cls, cls.token_pos(), |
2372 "typedef '%s' illegally refers to itself", | 2358 "typedef '%s' illegally refers to itself", |
2373 name.ToCString()); | 2359 name.ToCString()); |
2374 } | 2360 } |
2375 cls.set_is_type_finalized(); | 2361 cls.set_is_type_finalized(); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2583 // No cycles. | 2569 // No cycles. |
2584 return true; | 2570 return true; |
2585 } | 2571 } |
2586 | 2572 |
2587 | 2573 |
2588 // Returns false if a function type alias illegally refers to itself. | 2574 // Returns false if a function type alias illegally refers to itself. |
2589 bool ClassFinalizer::IsTypedefCycleFree(const Class& cls, | 2575 bool ClassFinalizer::IsTypedefCycleFree(const Class& cls, |
2590 const AbstractType& type, | 2576 const AbstractType& type, |
2591 GrowableArray<intptr_t>* visited) { | 2577 GrowableArray<intptr_t>* visited) { |
2592 ASSERT(visited != NULL); | 2578 ASSERT(visited != NULL); |
2593 AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type)); | 2579 ResolveType(cls, type); |
2594 bool checking_typedef = false; | 2580 bool checking_typedef = false; |
2595 if ((resolved_type.IsType() || resolved_type.IsFunctionType()) && | 2581 if (type.IsType() && !type.IsMalformed()) { |
2596 !resolved_type.IsMalformed()) { | |
2597 AbstractType& other_type = AbstractType::Handle(); | 2582 AbstractType& other_type = AbstractType::Handle(); |
2598 if (resolved_type.IsFunctionType()) { | 2583 if (type.IsFunctionType()) { |
2599 const Class& scope_class = Class::Handle(resolved_type.type_class()); | 2584 const Class& scope_class = Class::Handle(type.type_class()); |
2600 const Function& signature_function = | 2585 const Function& signature_function = |
2601 Function::Handle(FunctionType::Cast(resolved_type).signature()); | 2586 Function::Handle(Type::Cast(type).signature()); |
2602 // The signature function of this function type may be a local signature | 2587 // The signature function of this function type may be a local signature |
2603 // function used in a formal parameter type of the typedef signature, but | 2588 // function used in a formal parameter type of the typedef signature, but |
2604 // not the typedef signature function itself, thus not qualifying as an | 2589 // not the typedef signature function itself, thus not qualifying as an |
2605 // illegal self reference. | 2590 // illegal self reference. |
2606 if (!scope_class.is_type_finalized() && | 2591 if (!scope_class.is_type_finalized() && |
2607 scope_class.IsTypedefClass() && | 2592 scope_class.IsTypedefClass() && |
2608 (scope_class.signature_function() == signature_function.raw())) { | 2593 (scope_class.signature_function() == signature_function.raw())) { |
2609 checking_typedef = true; | 2594 checking_typedef = true; |
2610 const intptr_t scope_class_id = scope_class.id(); | 2595 const intptr_t scope_class_id = scope_class.id(); |
2611 ASSERT(visited != NULL); | 2596 ASSERT(visited != NULL); |
(...skipping 26 matching lines...) Expand all Loading... |
2638 } | 2623 } |
2639 // Check the parameter types of the signature of this function type. | 2624 // Check the parameter types of the signature of this function type. |
2640 const intptr_t num_parameters = signature_function.NumParameters(); | 2625 const intptr_t num_parameters = signature_function.NumParameters(); |
2641 for (intptr_t i = 0; i < num_parameters; i++) { | 2626 for (intptr_t i = 0; i < num_parameters; i++) { |
2642 other_type = signature_function.ParameterTypeAt(i); | 2627 other_type = signature_function.ParameterTypeAt(i); |
2643 if (!IsTypedefCycleFree(cls, other_type, visited)) { | 2628 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
2644 return false; | 2629 return false; |
2645 } | 2630 } |
2646 } | 2631 } |
2647 } | 2632 } |
2648 const TypeArguments& type_args = | 2633 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
2649 TypeArguments::Handle(resolved_type.arguments()); | |
2650 if (!type_args.IsNull()) { | 2634 if (!type_args.IsNull()) { |
2651 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2635 for (intptr_t i = 0; i < type_args.Length(); i++) { |
2652 other_type = type_args.TypeAt(i); | 2636 other_type = type_args.TypeAt(i); |
2653 if (!IsTypedefCycleFree(cls, other_type, visited)) { | 2637 if (!IsTypedefCycleFree(cls, other_type, visited)) { |
2654 return false; | 2638 return false; |
2655 } | 2639 } |
2656 } | 2640 } |
2657 } | 2641 } |
2658 if (checking_typedef) { | 2642 if (checking_typedef) { |
2659 visited->RemoveLast(); | 2643 visited->RemoveLast(); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2739 // and resolve super type and mixin types. | 2723 // and resolve super type and mixin types. |
2740 Zone* zone = Thread::Current()->zone(); | 2724 Zone* zone = Thread::Current()->zone(); |
2741 const Library& library = Library::Handle(zone, cls.library()); | 2725 const Library& library = Library::Handle(zone, cls.library()); |
2742 ASSERT(!library.IsNull()); | 2726 ASSERT(!library.IsNull()); |
2743 const Script& script = Script::Handle(zone, cls.script()); | 2727 const Script& script = Script::Handle(zone, cls.script()); |
2744 ASSERT(!script.IsNull()); | 2728 ASSERT(!script.IsNull()); |
2745 const GrowableObjectArray& type_args = | 2729 const GrowableObjectArray& type_args = |
2746 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); | 2730 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
2747 AbstractType& mixin_super_type = | 2731 AbstractType& mixin_super_type = |
2748 AbstractType::Handle(zone, mixin_app_type.super_type()); | 2732 AbstractType::Handle(zone, mixin_app_type.super_type()); |
2749 mixin_super_type = ResolveType(cls, mixin_super_type); | 2733 ResolveType(cls, mixin_super_type); |
2750 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. | 2734 ASSERT(mixin_super_type.HasResolvedTypeClass()); // Even if malformed. |
2751 if (mixin_super_type.IsMalformedOrMalbounded()) { | 2735 if (mixin_super_type.IsMalformedOrMalbounded()) { |
2752 ReportError(Error::Handle(zone, mixin_super_type.error())); | 2736 ReportError(Error::Handle(zone, mixin_super_type.error())); |
2753 } | 2737 } |
2754 if (mixin_super_type.IsDynamicType()) { | 2738 if (mixin_super_type.IsDynamicType()) { |
2755 ReportError(cls, cls.token_pos(), | 2739 ReportError(cls, cls.token_pos(), |
2756 "class '%s' may not extend 'dynamic'", | 2740 "class '%s' may not extend 'dynamic'", |
2757 String::Handle(zone, cls.Name()).ToCString()); | 2741 String::Handle(zone, cls.Name()).ToCString()); |
2758 } | 2742 } |
2759 // The super type may have a BoundedType as type argument, but cannot be | 2743 // The super type may have a BoundedType as type argument, but cannot be |
2760 // a BoundedType itself. | 2744 // a BoundedType itself. |
2761 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); | 2745 CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args); |
2762 AbstractType& mixin_type = AbstractType::Handle(zone); | 2746 AbstractType& mixin_type = AbstractType::Handle(zone); |
2763 Class& mixin_type_class = Class::Handle(zone); | 2747 Class& mixin_type_class = Class::Handle(zone); |
2764 Class& mixin_app_class = Class::Handle(zone); | 2748 Class& mixin_app_class = Class::Handle(zone); |
2765 String& mixin_app_class_name = String::Handle(zone); | 2749 String& mixin_app_class_name = String::Handle(zone); |
2766 String& mixin_type_class_name = String::Handle(zone); | 2750 String& mixin_type_class_name = String::Handle(zone); |
2767 AbstractType& super_type_arg = AbstractType::Handle(zone); | 2751 AbstractType& super_type_arg = AbstractType::Handle(zone); |
2768 AbstractType& mixin_type_arg = AbstractType::Handle(zone); | 2752 AbstractType& mixin_type_arg = AbstractType::Handle(zone); |
2769 const intptr_t depth = mixin_app_type.Depth(); | 2753 const intptr_t depth = mixin_app_type.Depth(); |
2770 for (intptr_t i = 0; i < depth; i++) { | 2754 for (intptr_t i = 0; i < depth; i++) { |
2771 mixin_type = mixin_app_type.MixinTypeAt(i); | 2755 mixin_type = mixin_app_type.MixinTypeAt(i); |
2772 ASSERT(!mixin_type.IsNull()); | 2756 ASSERT(!mixin_type.IsNull()); |
2773 mixin_type = ResolveType(cls, mixin_type); | 2757 ResolveType(cls, mixin_type); |
2774 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. | 2758 ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed. |
2775 ASSERT(mixin_type.IsType()); | 2759 ASSERT(mixin_type.IsType()); |
2776 const intptr_t num_super_type_args = type_args.Length(); | 2760 const intptr_t num_super_type_args = type_args.Length(); |
2777 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); | 2761 CollectTypeArguments(cls, Type::Cast(mixin_type), type_args); |
2778 | 2762 |
2779 // If the mixin type has identical type arguments as the super type, they | 2763 // If the mixin type has identical type arguments as the super type, they |
2780 // can share the same type parameters of the mixin application class, | 2764 // can share the same type parameters of the mixin application class, |
2781 // thereby allowing for further optimizations, such as instantiator vector | 2765 // thereby allowing for further optimizations, such as instantiator vector |
2782 // reuse or sharing of type arguments with the super class. | 2766 // reuse or sharing of type arguments with the super class. |
2783 bool share_type_params = (num_super_type_args > 0) && | 2767 bool share_type_params = (num_super_type_args > 0) && |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2924 // If cls belongs to core lib, restrictions about allowed interfaces | 2908 // If cls belongs to core lib, restrictions about allowed interfaces |
2925 // are lifted. | 2909 // are lifted. |
2926 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); | 2910 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); |
2927 | 2911 |
2928 // Resolve and check the super type and interfaces of cls. | 2912 // Resolve and check the super type and interfaces of cls. |
2929 visited->Add(cls_index); | 2913 visited->Add(cls_index); |
2930 AbstractType& interface = AbstractType::Handle(zone); | 2914 AbstractType& interface = AbstractType::Handle(zone); |
2931 Class& interface_class = Class::Handle(zone); | 2915 Class& interface_class = Class::Handle(zone); |
2932 | 2916 |
2933 // Resolve super type. Failures lead to a longjmp. | 2917 // Resolve super type. Failures lead to a longjmp. |
2934 super_type = ResolveType(cls, super_type); | 2918 ResolveType(cls, super_type); |
2935 if (super_type.IsMalformedOrMalbounded()) { | 2919 if (super_type.IsMalformedOrMalbounded()) { |
2936 ReportError(Error::Handle(zone, super_type.error())); | 2920 ReportError(Error::Handle(zone, super_type.error())); |
2937 } | 2921 } |
2938 if (super_type.IsDynamicType()) { | 2922 if (super_type.IsDynamicType()) { |
2939 ReportError(cls, cls.token_pos(), | 2923 ReportError(cls, cls.token_pos(), |
2940 "class '%s' may not extend 'dynamic'", | 2924 "class '%s' may not extend 'dynamic'", |
2941 String::Handle(zone, cls.Name()).ToCString()); | 2925 String::Handle(zone, cls.Name()).ToCString()); |
2942 } | 2926 } |
2943 interface_class = super_type.type_class(); | 2927 interface_class = super_type.type_class(); |
2944 if (interface_class.IsTypedefClass()) { | 2928 if (interface_class.IsTypedefClass()) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3004 String::Handle(zone, cls.Name()).ToCString(), | 2988 String::Handle(zone, cls.Name()).ToCString(), |
3005 interface_name.ToCString()); | 2989 interface_name.ToCString()); |
3006 } | 2990 } |
3007 } | 2991 } |
3008 // Now resolve the super interfaces of the super type. | 2992 // Now resolve the super interfaces of the super type. |
3009 ResolveSuperTypeAndInterfaces(interface_class, visited); | 2993 ResolveSuperTypeAndInterfaces(interface_class, visited); |
3010 | 2994 |
3011 // Resolve interfaces. Failures lead to a longjmp. | 2995 // Resolve interfaces. Failures lead to a longjmp. |
3012 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 2996 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
3013 interface ^= super_interfaces.At(i); | 2997 interface ^= super_interfaces.At(i); |
3014 interface = ResolveType(cls, interface); | 2998 ResolveType(cls, interface); |
3015 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 2999 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
3016 // A malbounded interface is only reported when involved in a type test. | 3000 // A malbounded interface is only reported when involved in a type test. |
3017 if (interface.IsMalformed()) { | 3001 if (interface.IsMalformed()) { |
3018 ReportError(Error::Handle(zone, interface.error())); | 3002 ReportError(Error::Handle(zone, interface.error())); |
3019 } | 3003 } |
3020 if (interface.IsDynamicType()) { | 3004 if (interface.IsDynamicType()) { |
3021 ReportError(cls, cls.token_pos(), | 3005 ReportError(cls, cls.token_pos(), |
3022 "'dynamic' may not be used as interface"); | 3006 "'dynamic' may not be used as interface"); |
3023 } | 3007 } |
3024 interface_class = interface.type_class(); | 3008 interface_class = interface.type_class(); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3321 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); | 3305 ASSERT(fields_array.Length() == ByteBuffer::NumberOfFields()); |
3322 field ^= fields_array.At(0); | 3306 field ^= fields_array.At(0); |
3323 ASSERT(field.Offset() == ByteBuffer::data_offset()); | 3307 ASSERT(field.Offset() == ByteBuffer::data_offset()); |
3324 name ^= field.name(); | 3308 name ^= field.name(); |
3325 expected_name ^= String::New("_data"); | 3309 expected_name ^= String::New("_data"); |
3326 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 3310 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
3327 #endif | 3311 #endif |
3328 } | 3312 } |
3329 | 3313 |
3330 } // namespace dart | 3314 } // namespace dart |
OLD | NEW |