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 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 // of the redirection chain. | 395 // of the redirection chain. |
396 ResolveRedirectingFactoryTarget(target_class, target, visited_factories); | 396 ResolveRedirectingFactoryTarget(target_class, target, visited_factories); |
397 Type& target_type = Type::Handle(target.RedirectionType()); | 397 Type& target_type = Type::Handle(target.RedirectionType()); |
398 Function& target_target = Function::Handle(target.RedirectionTarget()); | 398 Function& target_target = Function::Handle(target.RedirectionTarget()); |
399 if (target_target.IsNull()) { | 399 if (target_target.IsNull()) { |
400 ASSERT(target_type.IsMalformed()); | 400 ASSERT(target_type.IsMalformed()); |
401 } else { | 401 } else { |
402 // If the target type refers to type parameters, substitute them with the | 402 // If the target type refers to type parameters, substitute them with the |
403 // type arguments of the redirection type. | 403 // type arguments of the redirection type. |
404 if (!target_type.IsInstantiated()) { | 404 if (!target_type.IsInstantiated()) { |
405 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( | 405 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
406 type.arguments()); | |
407 Error& bound_error = Error::Handle(); | 406 Error& bound_error = Error::Handle(); |
408 target_type ^= target_type.InstantiateFrom(type_args, &bound_error); | 407 target_type ^= target_type.InstantiateFrom(type_args, &bound_error); |
409 if (bound_error.IsNull()) { | 408 if (bound_error.IsNull()) { |
410 target_type ^= FinalizeType(cls, target_type, kCanonicalize); | 409 target_type ^= FinalizeType(cls, target_type, kCanonicalize); |
411 } else { | 410 } else { |
412 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); | 411 ASSERT(target_type.IsInstantiated() && type_args.IsInstantiated()); |
413 const Script& script = Script::Handle(target_class.script()); | 412 const Script& script = Script::Handle(target_class.script()); |
414 FinalizeMalformedType(bound_error, script, target_type, | 413 FinalizeMalformedType(bound_error, script, target_type, |
415 "cannot resolve redirecting factory"); | 414 "cannot resolve redirecting factory"); |
416 target_target = Function::null(); | 415 target_target = Function::null(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 parameterized_type, | 453 parameterized_type, |
455 "cannot resolve class '%s' from '%s'", | 454 "cannot resolve class '%s' from '%s'", |
456 String::Handle(unresolved_class.Name()).ToCString(), | 455 String::Handle(unresolved_class.Name()).ToCString(), |
457 String::Handle(cls.Name()).ToCString()); | 456 String::Handle(cls.Name()).ToCString()); |
458 return; | 457 return; |
459 } | 458 } |
460 parameterized_type.set_type_class(type_class); | 459 parameterized_type.set_type_class(type_class); |
461 } | 460 } |
462 | 461 |
463 // Resolve type arguments, if any. | 462 // Resolve type arguments, if any. |
464 const AbstractTypeArguments& arguments = | 463 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
465 AbstractTypeArguments::Handle(type.arguments()); | |
466 if (!arguments.IsNull()) { | 464 if (!arguments.IsNull()) { |
467 const intptr_t num_arguments = arguments.Length(); | 465 const intptr_t num_arguments = arguments.Length(); |
468 AbstractType& type_argument = AbstractType::Handle(); | 466 AbstractType& type_argument = AbstractType::Handle(); |
469 for (intptr_t i = 0; i < num_arguments; i++) { | 467 for (intptr_t i = 0; i < num_arguments; i++) { |
470 type_argument = arguments.TypeAt(i); | 468 type_argument = arguments.TypeAt(i); |
471 ResolveType(cls, type_argument); | 469 ResolveType(cls, type_argument); |
472 } | 470 } |
473 } | 471 } |
474 } | 472 } |
475 | 473 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 // cls = C, arguments = [dynamic, String, double], | 522 // cls = C, arguments = [dynamic, String, double], |
525 // num_uninitialized_arguments = 1, | 523 // num_uninitialized_arguments = 1, |
526 // i.e. cls_args = [String, double], offset = 1, length = 2. | 524 // i.e. cls_args = [String, double], offset = 1, length = 2. |
527 // Output: arguments = [int, String, double] | 525 // Output: arguments = [int, String, double] |
528 // | 526 // |
529 // It is too early to canonicalize the type arguments of the vector, because | 527 // It is too early to canonicalize the type arguments of the vector, because |
530 // several type argument vectors may be mutually recursive and finalized at the | 528 // several type argument vectors may be mutually recursive and finalized at the |
531 // same time. Canonicalization happens when pending types are processed. | 529 // same time. Canonicalization happens when pending types are processed. |
532 void ClassFinalizer::FinalizeTypeArguments( | 530 void ClassFinalizer::FinalizeTypeArguments( |
533 const Class& cls, | 531 const Class& cls, |
534 const AbstractTypeArguments& arguments, | 532 const TypeArguments& arguments, |
535 intptr_t num_uninitialized_arguments, | 533 intptr_t num_uninitialized_arguments, |
536 Error* bound_error, | 534 Error* bound_error, |
537 GrowableObjectArray* pending_types) { | 535 GrowableObjectArray* pending_types) { |
538 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 536 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
539 if (!cls.is_type_finalized()) { | 537 if (!cls.is_type_finalized()) { |
540 FinalizeTypeParameters(cls, pending_types); | 538 FinalizeTypeParameters(cls, pending_types); |
541 ResolveUpperBounds(cls); | 539 ResolveUpperBounds(cls); |
542 } | 540 } |
543 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 541 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
544 if (!super_type.IsNull()) { | 542 if (!super_type.IsNull()) { |
545 const Class& super_class = Class::Handle(super_type.type_class()); | 543 const Class& super_class = Class::Handle(super_type.type_class()); |
546 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 544 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
547 const intptr_t num_super_type_args = super_class.NumTypeArguments(); | 545 const intptr_t num_super_type_args = super_class.NumTypeArguments(); |
548 ASSERT(num_super_type_args == | 546 ASSERT(num_super_type_args == |
549 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); | 547 (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); |
550 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { | 548 if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { |
551 super_type ^= FinalizeType( | 549 super_type ^= FinalizeType( |
552 cls, super_type, kFinalize, pending_types); | 550 cls, super_type, kFinalize, pending_types); |
553 cls.set_super_type(super_type); | 551 cls.set_super_type(super_type); |
554 } | 552 } |
555 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle( | 553 TypeArguments& super_type_args = TypeArguments::Handle( |
556 super_type.arguments()); | 554 super_type.arguments()); |
557 // Offset of super type's type parameters in cls' type argument vector. | 555 // Offset of super type's type parameters in cls' type argument vector. |
558 const intptr_t super_offset = num_super_type_args - num_super_type_params; | 556 const intptr_t super_offset = num_super_type_args - num_super_type_params; |
559 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); | 557 AbstractType& super_type_arg = AbstractType::Handle(Type::DynamicType()); |
560 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { | 558 for (intptr_t i = super_offset; i < num_uninitialized_arguments; i++) { |
561 if (!super_type_args.IsNull()) { | 559 if (!super_type_args.IsNull()) { |
562 super_type_arg = super_type_args.TypeAt(i); | 560 super_type_arg = super_type_args.TypeAt(i); |
563 if (!super_type_arg.IsFinalized()) { | 561 if (!super_type_arg.IsFinalized()) { |
564 super_type_arg ^= FinalizeType( | 562 super_type_arg ^= FinalizeType( |
565 cls, super_type_arg, kFinalize, pending_types); | 563 cls, super_type_arg, kFinalize, pending_types); |
(...skipping 21 matching lines...) Expand all Loading... |
587 bound_error, pending_types); | 585 bound_error, pending_types); |
588 } | 586 } |
589 } | 587 } |
590 | 588 |
591 | 589 |
592 // Check the type argument vector 'arguments' against the corresponding bounds | 590 // Check the type argument vector 'arguments' against the corresponding bounds |
593 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 591 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
594 // Replace a type argument that cannot be checked at compile time by a | 592 // Replace a type argument that cannot be checked at compile time by a |
595 // BoundedType, thereby postponing the bound check to run time. | 593 // BoundedType, thereby postponing the bound check to run time. |
596 // Return a bound error if a type argument is not within bound at compile time. | 594 // Return a bound error if a type argument is not within bound at compile time. |
597 void ClassFinalizer::CheckTypeArgumentBounds( | 595 void ClassFinalizer::CheckTypeArgumentBounds(const Class& cls, |
598 const Class& cls, | 596 const TypeArguments& arguments, |
599 const AbstractTypeArguments& arguments, | 597 Error* bound_error) { |
600 Error* bound_error) { | |
601 if (!cls.is_type_finalized()) { | 598 if (!cls.is_type_finalized()) { |
602 FinalizeUpperBounds(cls); | 599 FinalizeUpperBounds(cls); |
603 } | 600 } |
604 // Note that when finalizing a type, we need to verify the bounds in both | 601 // Note that when finalizing a type, we need to verify the bounds in both |
605 // production mode and checked mode, because the finalized type may be written | 602 // production mode and checked mode, because the finalized type may be written |
606 // to a snapshot. It would be wrong to ignore bounds when generating the | 603 // to a snapshot. It would be wrong to ignore bounds when generating the |
607 // snapshot in production mode and then use the unchecked type in checked mode | 604 // snapshot in production mode and then use the unchecked type in checked mode |
608 // after reading it from the snapshot. | 605 // after reading it from the snapshot. |
609 // However, we do not immediately report a bound error, which would be wrong | 606 // However, we do not immediately report a bound error, which would be wrong |
610 // in production mode, but simply postpone the bound checking to runtime. | 607 // in production mode, but simply postpone the bound checking to runtime. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 680 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
684 if (!super_type.IsNull()) { | 681 if (!super_type.IsNull()) { |
685 const Class& super_class = Class::Handle(super_type.type_class()); | 682 const Class& super_class = Class::Handle(super_type.type_class()); |
686 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 683 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
687 } | 684 } |
688 } | 685 } |
689 | 686 |
690 | 687 |
691 void ClassFinalizer::CheckTypeBounds(const Class& cls, const Type& type) { | 688 void ClassFinalizer::CheckTypeBounds(const Class& cls, const Type& type) { |
692 ASSERT(type.IsFinalized()); | 689 ASSERT(type.IsFinalized()); |
693 AbstractTypeArguments& arguments = | 690 TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
694 AbstractTypeArguments::Handle(type.arguments()); | |
695 if (arguments.IsNull()) { | 691 if (arguments.IsNull()) { |
696 return; | 692 return; |
697 } | 693 } |
698 Class& owner_class = Class::Handle(); | 694 Class& owner_class = Class::Handle(); |
699 Class& type_class = Class::Handle(type.type_class()); | 695 Class& type_class = Class::Handle(type.type_class()); |
700 if (type_class.IsSignatureClass()) { | 696 if (type_class.IsSignatureClass()) { |
701 const Function& signature_fun = | 697 const Function& signature_fun = |
702 Function::Handle(type_class.signature_function()); | 698 Function::Handle(type_class.signature_function()); |
703 ASSERT(!signature_fun.is_static()); | 699 ASSERT(!signature_fun.is_static()); |
704 owner_class = signature_fun.Owner(); | 700 owner_class = signature_fun.Owner(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 | 819 |
824 // The finalized type argument vector needs num_type_arguments types. | 820 // The finalized type argument vector needs num_type_arguments types. |
825 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 821 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
826 // The type class has num_type_parameters type parameters. | 822 // The type class has num_type_parameters type parameters. |
827 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 823 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
828 | 824 |
829 // Initialize the type argument vector. | 825 // Initialize the type argument vector. |
830 // Check the number of parsed type arguments, if any. | 826 // Check the number of parsed type arguments, if any. |
831 // Specifying no type arguments indicates a raw type, which is not an error. | 827 // Specifying no type arguments indicates a raw type, which is not an error. |
832 // However, type parameter bounds are checked below, even for a raw type. | 828 // However, type parameter bounds are checked below, even for a raw type. |
833 AbstractTypeArguments& arguments = | 829 TypeArguments& arguments = |
834 AbstractTypeArguments::Handle(parameterized_type.arguments()); | 830 TypeArguments::Handle(parameterized_type.arguments()); |
835 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 831 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
836 // Wrong number of type arguments. The type is mapped to the raw type. | 832 // Wrong number of type arguments. The type is mapped to the raw type. |
837 if (FLAG_error_on_bad_type) { | 833 if (FLAG_error_on_bad_type) { |
838 const Script& script = Script::Handle(cls.script()); | 834 const Script& script = Script::Handle(cls.script()); |
839 const String& type_class_name = String::Handle(type_class.Name()); | 835 const String& type_class_name = String::Handle(type_class.Name()); |
840 ReportError(Error::Handle(), // No previous error. | 836 ReportError(Error::Handle(), // No previous error. |
841 script, parameterized_type.token_pos(), | 837 script, parameterized_type.token_pos(), |
842 "wrong number of type arguments for class '%s'", | 838 "wrong number of type arguments for class '%s'", |
843 type_class_name.ToCString()); | 839 type_class_name.ToCString()); |
844 } | 840 } |
845 // Make the type raw and continue without reporting any error. | 841 // Make the type raw and continue without reporting any error. |
846 // A static warning should have been reported. | 842 // A static warning should have been reported. |
847 arguments = AbstractTypeArguments::null(); | 843 arguments = TypeArguments::null(); |
848 parameterized_type.set_arguments(arguments); | 844 parameterized_type.set_arguments(arguments); |
849 } | 845 } |
850 | 846 |
851 // The full type argument vector consists of the type arguments of the | 847 // The full type argument vector consists of the type arguments of the |
852 // super types of type_class, which are initialized from the parsed | 848 // super types of type_class, which are initialized from the parsed |
853 // type arguments, followed by the parsed type arguments. | 849 // type arguments, followed by the parsed type arguments. |
854 TypeArguments& full_arguments = TypeArguments::Handle(); | 850 TypeArguments& full_arguments = TypeArguments::Handle(); |
855 Error& bound_error = Error::Handle(); | 851 Error& bound_error = Error::Handle(); |
856 if (num_type_arguments > 0) { | 852 if (num_type_arguments > 0) { |
857 // If no type arguments were parsed and if the super types do not prepend | 853 // If no type arguments were parsed and if the super types do not prepend |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 // function type to refer to itself via its parameter types and result type. | 952 // function type to refer to itself via its parameter types and result type. |
957 if (type_class.IsSignatureClass()) { | 953 if (type_class.IsSignatureClass()) { |
958 // The class may be created while parsing a function body, after all | 954 // The class may be created while parsing a function body, after all |
959 // pending classes have already been finalized. | 955 // pending classes have already been finalized. |
960 FinalizeTypesInClass(type_class); | 956 FinalizeTypesInClass(type_class); |
961 } | 957 } |
962 | 958 |
963 if (FLAG_trace_type_finalization) { | 959 if (FLAG_trace_type_finalization) { |
964 OS::Print("Done finalizing type '%s' with %" Pd " type args: %s\n", | 960 OS::Print("Done finalizing type '%s' with %" Pd " type args: %s\n", |
965 String::Handle(parameterized_type.Name()).ToCString(), | 961 String::Handle(parameterized_type.Name()).ToCString(), |
966 parameterized_type.arguments() == AbstractTypeArguments::null() ? | 962 parameterized_type.arguments() == TypeArguments::null() ? |
967 0 : num_type_arguments, | 963 0 : num_type_arguments, |
968 parameterized_type.ToCString()); | 964 parameterized_type.ToCString()); |
969 } | 965 } |
970 | 966 |
971 if (finalization >= kCanonicalize) { | 967 if (finalization >= kCanonicalize) { |
972 return parameterized_type.Canonicalize(); | 968 return parameterized_type.Canonicalize(); |
973 } else { | 969 } else { |
974 return parameterized_type.raw(); | 970 return parameterized_type.raw(); |
975 } | 971 } |
976 } | 972 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 } | 1039 } |
1044 return Class::null(); | 1040 return Class::null(); |
1045 } | 1041 } |
1046 | 1042 |
1047 | 1043 |
1048 // Resolve the upper bounds of the type parameters of class cls. | 1044 // Resolve the upper bounds of the type parameters of class cls. |
1049 void ClassFinalizer::ResolveUpperBounds(const Class& cls) { | 1045 void ClassFinalizer::ResolveUpperBounds(const Class& cls) { |
1050 const intptr_t num_type_params = cls.NumTypeParameters(); | 1046 const intptr_t num_type_params = cls.NumTypeParameters(); |
1051 TypeParameter& type_param = TypeParameter::Handle(); | 1047 TypeParameter& type_param = TypeParameter::Handle(); |
1052 AbstractType& bound = AbstractType::Handle(); | 1048 AbstractType& bound = AbstractType::Handle(); |
1053 const AbstractTypeArguments& type_params = | 1049 const TypeArguments& type_params = |
1054 AbstractTypeArguments::Handle(cls.type_parameters()); | 1050 TypeArguments::Handle(cls.type_parameters()); |
1055 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1051 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
1056 (type_params.Length() == num_type_params)); | 1052 (type_params.Length() == num_type_params)); |
1057 // In a first pass, resolve all bounds. This guarantees that finalization | 1053 // In a first pass, resolve all bounds. This guarantees that finalization |
1058 // of mutually referencing bounds will not encounter an unresolved bound. | 1054 // of mutually referencing bounds will not encounter an unresolved bound. |
1059 for (intptr_t i = 0; i < num_type_params; i++) { | 1055 for (intptr_t i = 0; i < num_type_params; i++) { |
1060 type_param ^= type_params.TypeAt(i); | 1056 type_param ^= type_params.TypeAt(i); |
1061 bound = type_param.bound(); | 1057 bound = type_param.bound(); |
1062 ResolveType(cls, bound); | 1058 ResolveType(cls, bound); |
1063 } | 1059 } |
1064 } | 1060 } |
1065 | 1061 |
1066 | 1062 |
1067 // Finalize the upper bounds of the type parameters of class cls. | 1063 // Finalize the upper bounds of the type parameters of class cls. |
1068 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { | 1064 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { |
1069 const intptr_t num_type_params = cls.NumTypeParameters(); | 1065 const intptr_t num_type_params = cls.NumTypeParameters(); |
1070 TypeParameter& type_param = TypeParameter::Handle(); | 1066 TypeParameter& type_param = TypeParameter::Handle(); |
1071 AbstractType& bound = AbstractType::Handle(); | 1067 AbstractType& bound = AbstractType::Handle(); |
1072 const AbstractTypeArguments& type_params = | 1068 const TypeArguments& type_params = |
1073 AbstractTypeArguments::Handle(cls.type_parameters()); | 1069 TypeArguments::Handle(cls.type_parameters()); |
1074 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1070 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
1075 (type_params.Length() == num_type_params)); | 1071 (type_params.Length() == num_type_params)); |
1076 for (intptr_t i = 0; i < num_type_params; i++) { | 1072 for (intptr_t i = 0; i < num_type_params; i++) { |
1077 type_param ^= type_params.TypeAt(i); | 1073 type_param ^= type_params.TypeAt(i); |
1078 bound = type_param.bound(); | 1074 bound = type_param.bound(); |
1079 if (bound.IsFinalized() || bound.IsBeingFinalized()) { | 1075 if (bound.IsFinalized() || bound.IsBeingFinalized()) { |
1080 // A bound involved in F-bounded quantification may form a cycle. | 1076 // A bound involved in F-bounded quantification may form a cycle. |
1081 continue; | 1077 continue; |
1082 } | 1078 } |
1083 bound = FinalizeType(cls, bound, kCanonicalize); | 1079 bound = FinalizeType(cls, bound, kCanonicalize); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 Error& error = Error::Handle(); | 1180 Error& error = Error::Handle(); |
1185 if (type.IsMalformedOrMalbounded()) { | 1181 if (type.IsMalformedOrMalbounded()) { |
1186 error = type.error(); | 1182 error = type.error(); |
1187 } else { | 1183 } else { |
1188 ASSERT(type.IsInstantiated()); | 1184 ASSERT(type.IsInstantiated()); |
1189 } | 1185 } |
1190 const Instance& const_value = Instance::Handle(field.value()); | 1186 const Instance& const_value = Instance::Handle(field.value()); |
1191 if (!error.IsNull() || | 1187 if (!error.IsNull() || |
1192 (!type.IsDynamicType() && | 1188 (!type.IsDynamicType() && |
1193 !const_value.IsInstanceOf(type, | 1189 !const_value.IsInstanceOf(type, |
1194 AbstractTypeArguments::Handle(), | 1190 Object::null_type_arguments(), |
1195 &error))) { | 1191 &error))) { |
1196 if (FLAG_error_on_bad_type) { | 1192 if (FLAG_error_on_bad_type) { |
1197 const AbstractType& const_value_type = AbstractType::Handle( | 1193 const AbstractType& const_value_type = AbstractType::Handle( |
1198 const_value.GetType()); | 1194 const_value.GetType()); |
1199 const String& const_value_type_name = String::Handle( | 1195 const String& const_value_type_name = String::Handle( |
1200 const_value_type.UserVisibleName()); | 1196 const_value_type.UserVisibleName()); |
1201 const String& type_name = String::Handle(type.UserVisibleName()); | 1197 const String& type_name = String::Handle(type.UserVisibleName()); |
1202 const Script& script = Script::Handle(cls.script()); | 1198 const Script& script = Script::Handle(cls.script()); |
1203 ReportError(error, script, field.token_pos(), | 1199 ReportError(error, script, field.token_pos(), |
1204 "error initializing static %s field '%s': " | 1200 "error initializing static %s field '%s': " |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 // Example: | 1375 // Example: |
1380 // class S<T> { } | 1376 // class S<T> { } |
1381 // class M<T> { } | 1377 // class M<T> { } |
1382 // class C<E> extends S<E> with M<List<E>> { } | 1378 // class C<E> extends S<E> with M<List<E>> { } |
1383 // results in | 1379 // results in |
1384 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> | 1380 // class S&M<T`, T> extends S<T`> implements M<T> { } // mixin == M<T> |
1385 // class C<E> extends S&M<E, List<E>> { } | 1381 // class C<E> extends S&M<E, List<E>> { } |
1386 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and | 1382 // CloneMixinAppTypeParameters decorates class S&M with type parameters T` and |
1387 // T, and use them as type arguments in S<T`> and M<T>. | 1383 // T, and use them as type arguments in S<T`> and M<T>. |
1388 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { | 1384 void ClassFinalizer::CloneMixinAppTypeParameters(const Class& mixin_app_class) { |
1389 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); | 1385 ASSERT(mixin_app_class.type_parameters() == TypeArguments::null()); |
1390 Isolate* isolate = Isolate::Current(); | 1386 Isolate* isolate = Isolate::Current(); |
1391 const AbstractType& super_type = AbstractType::Handle(isolate, | 1387 const AbstractType& super_type = AbstractType::Handle(isolate, |
1392 mixin_app_class.super_type()); | 1388 mixin_app_class.super_type()); |
1393 ASSERT(super_type.IsResolved()); | 1389 ASSERT(super_type.IsResolved()); |
1394 const Class& super_class = Class::Handle(isolate, super_type.type_class()); | 1390 const Class& super_class = Class::Handle(isolate, super_type.type_class()); |
1395 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 1391 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
1396 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); | 1392 const Type& mixin_type = Type::Handle(isolate, mixin_app_class.mixin()); |
1397 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); | 1393 const Class& mixin_class = Class::Handle(isolate, mixin_type.type_class()); |
1398 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); | 1394 const intptr_t num_mixin_type_params = mixin_class.NumTypeParameters(); |
1399 // The mixin class cannot be Object and this was checked earlier. | 1395 // The mixin class cannot be Object and this was checked earlier. |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1657 // CloneMixinAppTypeParameters on the inserted class, as long as the super | 1653 // CloneMixinAppTypeParameters on the inserted class, as long as the super |
1658 // type class is set properly. | 1654 // type class is set properly. |
1659 inserted_class.set_super_type(super_type); // Super class only is used. | 1655 inserted_class.set_super_type(super_type); // Super class only is used. |
1660 | 1656 |
1661 // The mixin type and interface type must also be set before calling | 1657 // The mixin type and interface type must also be set before calling |
1662 // CloneMixinAppTypeParameters. | 1658 // CloneMixinAppTypeParameters. |
1663 // After FinalizeTypesInClass, they will refer to the type parameters of | 1659 // After FinalizeTypesInClass, they will refer to the type parameters of |
1664 // the mixin class typedef. | 1660 // the mixin class typedef. |
1665 const Type& generic_mixin_type = Type::Handle(isolate, | 1661 const Type& generic_mixin_type = Type::Handle(isolate, |
1666 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()), | 1662 Type::New(Class::Handle(isolate, aliased_mixin_type.type_class()), |
1667 Object::null_abstract_type_arguments(), | 1663 Object::null_type_arguments(), |
1668 aliased_mixin_type.token_pos())); | 1664 aliased_mixin_type.token_pos())); |
1669 inserted_class.set_mixin(generic_mixin_type); | 1665 inserted_class.set_mixin(generic_mixin_type); |
1670 // The interface will be set in CloneMixinAppTypeParameters. | 1666 // The interface will be set in CloneMixinAppTypeParameters. |
1671 } | 1667 } |
1672 | 1668 |
1673 // Finalize the types and call CloneMixinAppTypeParameters. | 1669 // Finalize the types and call CloneMixinAppTypeParameters. |
1674 FinalizeTypesInClass(inserted_class); | 1670 FinalizeTypesInClass(inserted_class); |
1675 | 1671 |
1676 // The super type of this mixin application class must point to the | 1672 // The super type of this mixin application class must point to the |
1677 // inserted class. The super type arguments are the concatenation of the | 1673 // inserted class. The super type arguments are the concatenation of the |
(...skipping 29 matching lines...) Expand all Loading... |
1707 const Class& aliased_mixin_type_class = Class::Handle(isolate, | 1703 const Class& aliased_mixin_type_class = Class::Handle(isolate, |
1708 aliased_mixin_type.type_class()); | 1704 aliased_mixin_type.type_class()); |
1709 const intptr_t num_aliased_mixin_type_params = | 1705 const intptr_t num_aliased_mixin_type_params = |
1710 aliased_mixin_type_class.NumTypeParameters(); | 1706 aliased_mixin_type_class.NumTypeParameters(); |
1711 const intptr_t num_aliased_mixin_type_args = | 1707 const intptr_t num_aliased_mixin_type_args = |
1712 aliased_mixin_type_class.NumTypeArguments(); | 1708 aliased_mixin_type_class.NumTypeArguments(); |
1713 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; | 1709 offset = num_aliased_mixin_type_args - num_aliased_mixin_type_params; |
1714 ASSERT(inserted_class.NumTypeParameters() == | 1710 ASSERT(inserted_class.NumTypeParameters() == |
1715 (num_super_type_params + num_aliased_mixin_type_params)); | 1711 (num_super_type_params + num_aliased_mixin_type_params)); |
1716 // The aliased_mixin_type may be raw. | 1712 // The aliased_mixin_type may be raw. |
1717 const AbstractTypeArguments& mixin_class_super_type_args = | 1713 const TypeArguments& mixin_class_super_type_args = |
1718 AbstractTypeArguments::Handle(isolate, | 1714 TypeArguments::Handle(isolate, |
1719 AbstractType::Handle(isolate, mixin_class.super_type()).arguments()); | 1715 AbstractType::Handle(isolate, mixin_class.super_type()).arguments()); |
1720 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate); | 1716 TypeArguments& new_mixin_type_args = TypeArguments::Handle(isolate); |
1721 if ((num_aliased_mixin_type_params > 0) && | 1717 if ((num_aliased_mixin_type_params > 0) && |
1722 !mixin_class_super_type_args.IsNull()) { | 1718 !mixin_class_super_type_args.IsNull()) { |
1723 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); | 1719 new_mixin_type_args = TypeArguments::New(num_aliased_mixin_type_params); |
1724 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { | 1720 for (intptr_t i = 0; i < num_aliased_mixin_type_params; i++) { |
1725 type = mixin_class_super_type_args.TypeAt(offset + i); | 1721 type = mixin_class_super_type_args.TypeAt(offset + i); |
1726 new_mixin_type_args.SetTypeAt(i, type); | 1722 new_mixin_type_args.SetTypeAt(i, type); |
1727 } | 1723 } |
1728 } | 1724 } |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2217 GrowableArray<intptr_t>* visited) { | 2213 GrowableArray<intptr_t>* visited) { |
2218 ASSERT(visited != NULL); | 2214 ASSERT(visited != NULL); |
2219 ResolveType(cls, type); | 2215 ResolveType(cls, type); |
2220 if (type.IsType() && !type.IsMalformed()) { | 2216 if (type.IsType() && !type.IsMalformed()) { |
2221 const Class& type_class = Class::Handle(type.type_class()); | 2217 const Class& type_class = Class::Handle(type.type_class()); |
2222 if (!type_class.is_type_finalized() && | 2218 if (!type_class.is_type_finalized() && |
2223 type_class.IsSignatureClass() && | 2219 type_class.IsSignatureClass() && |
2224 !IsAliasCycleFree(type_class, visited)) { | 2220 !IsAliasCycleFree(type_class, visited)) { |
2225 return false; | 2221 return false; |
2226 } | 2222 } |
2227 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( | 2223 const TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
2228 type.arguments()); | |
2229 if (!type_args.IsNull()) { | 2224 if (!type_args.IsNull()) { |
2230 AbstractType& type_arg = AbstractType::Handle(); | 2225 AbstractType& type_arg = AbstractType::Handle(); |
2231 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2226 for (intptr_t i = 0; i < type_args.Length(); i++) { |
2232 type_arg = type_args.TypeAt(i); | 2227 type_arg = type_args.TypeAt(i); |
2233 if (!IsTypeCycleFree(cls, type_arg, visited)) { | 2228 if (!IsTypeCycleFree(cls, type_arg, visited)) { |
2234 return false; | 2229 return false; |
2235 } | 2230 } |
2236 } | 2231 } |
2237 } | 2232 } |
2238 } | 2233 } |
(...skipping 15 matching lines...) Expand all Loading... |
2254 } | 2249 } |
2255 } | 2250 } |
2256 | 2251 |
2257 // Visit the bounds, result type, and parameter types of this signature type. | 2252 // Visit the bounds, result type, and parameter types of this signature type. |
2258 visited->Add(cls.id()); | 2253 visited->Add(cls.id()); |
2259 AbstractType& type = AbstractType::Handle(); | 2254 AbstractType& type = AbstractType::Handle(); |
2260 | 2255 |
2261 // Check the bounds of this signature type. | 2256 // Check the bounds of this signature type. |
2262 const intptr_t num_type_params = cls.NumTypeParameters(); | 2257 const intptr_t num_type_params = cls.NumTypeParameters(); |
2263 TypeParameter& type_param = TypeParameter::Handle(); | 2258 TypeParameter& type_param = TypeParameter::Handle(); |
2264 const AbstractTypeArguments& type_params = | 2259 const TypeArguments& type_params = |
2265 AbstractTypeArguments::Handle(cls.type_parameters()); | 2260 TypeArguments::Handle(cls.type_parameters()); |
2266 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 2261 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
2267 (type_params.Length() == num_type_params)); | 2262 (type_params.Length() == num_type_params)); |
2268 for (intptr_t i = 0; i < num_type_params; i++) { | 2263 for (intptr_t i = 0; i < num_type_params; i++) { |
2269 type_param ^= type_params.TypeAt(i); | 2264 type_param ^= type_params.TypeAt(i); |
2270 type = type_param.bound(); | 2265 type = type_param.bound(); |
2271 if (!IsTypeCycleFree(cls, type, visited)) { | 2266 if (!IsTypeCycleFree(cls, type, visited)) { |
2272 return false; | 2267 return false; |
2273 } | 2268 } |
2274 } | 2269 } |
2275 // Check the result type of the function of this signature type. | 2270 // Check the result type of the function of this signature type. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2322 return true; | 2317 return true; |
2323 } | 2318 } |
2324 | 2319 |
2325 | 2320 |
2326 void ClassFinalizer::CollectTypeArguments( | 2321 void ClassFinalizer::CollectTypeArguments( |
2327 const Class& cls, | 2322 const Class& cls, |
2328 const Type& type, | 2323 const Type& type, |
2329 const GrowableObjectArray& collected_args) { | 2324 const GrowableObjectArray& collected_args) { |
2330 ASSERT(type.HasResolvedTypeClass()); | 2325 ASSERT(type.HasResolvedTypeClass()); |
2331 Class& type_class = Class::Handle(type.type_class()); | 2326 Class& type_class = Class::Handle(type.type_class()); |
2332 AbstractTypeArguments& type_args = | 2327 TypeArguments& type_args = TypeArguments::Handle(type.arguments()); |
2333 AbstractTypeArguments::Handle(type.arguments()); | |
2334 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 2328 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
2335 const intptr_t num_type_arguments = | 2329 const intptr_t num_type_arguments = |
2336 type_args.IsNull() ? 0 : type_args.Length(); | 2330 type_args.IsNull() ? 0 : type_args.Length(); |
2337 AbstractType& arg = AbstractType::Handle(); | 2331 AbstractType& arg = AbstractType::Handle(); |
2338 if (num_type_arguments > 0) { | 2332 if (num_type_arguments > 0) { |
2339 if (num_type_arguments == num_type_parameters) { | 2333 if (num_type_arguments == num_type_parameters) { |
2340 for (intptr_t i = 0; i < num_type_arguments; i++) { | 2334 for (intptr_t i = 0; i < num_type_arguments; i++) { |
2341 arg = type_args.TypeAt(i); | 2335 arg = type_args.TypeAt(i); |
2342 arg = arg.CloneUnfinalized(); | 2336 arg = arg.CloneUnfinalized(); |
2343 ASSERT(!arg.IsBeingFinalized()); | 2337 ASSERT(!arg.IsBeingFinalized()); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2437 mixin_type_class_name); | 2431 mixin_type_class_name); |
2438 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); | 2432 mixin_app_class = library.LookupLocalClass(mixin_app_class_name); |
2439 if (mixin_app_class.IsNull()) { | 2433 if (mixin_app_class.IsNull()) { |
2440 mixin_app_class_name = Symbols::New(mixin_app_class_name); | 2434 mixin_app_class_name = Symbols::New(mixin_app_class_name); |
2441 mixin_app_class = Class::New(mixin_app_class_name, | 2435 mixin_app_class = Class::New(mixin_app_class_name, |
2442 script, | 2436 script, |
2443 mixin_type.token_pos()); | 2437 mixin_type.token_pos()); |
2444 mixin_app_class.set_super_type(mixin_super_type); | 2438 mixin_app_class.set_super_type(mixin_super_type); |
2445 mixin_type_class = mixin_type.type_class(); | 2439 mixin_type_class = mixin_type.type_class(); |
2446 generic_mixin_type = Type::New(mixin_type_class, | 2440 generic_mixin_type = Type::New(mixin_type_class, |
2447 Object::null_abstract_type_arguments(), | 2441 Object::null_type_arguments(), |
2448 mixin_type.token_pos()); | 2442 mixin_type.token_pos()); |
2449 mixin_app_class.set_mixin(generic_mixin_type); | 2443 mixin_app_class.set_mixin(generic_mixin_type); |
2450 mixin_app_class.set_is_synthesized_class(); | 2444 mixin_app_class.set_is_synthesized_class(); |
2451 library.AddClass(mixin_app_class); | 2445 library.AddClass(mixin_app_class); |
2452 | 2446 |
2453 // No need to add the new class to pending_classes, since it will be | 2447 // No need to add the new class to pending_classes, since it will be |
2454 // processed via the super_type chain of a pending class. | 2448 // processed via the super_type chain of a pending class. |
2455 | 2449 |
2456 if (FLAG_trace_class_finalization) { | 2450 if (FLAG_trace_class_finalization) { |
2457 OS::Print("Creating mixin application %s\n", | 2451 OS::Print("Creating mixin application %s\n", |
2458 mixin_app_class.ToCString()); | 2452 mixin_app_class.ToCString()); |
2459 } | 2453 } |
2460 } | 2454 } |
2461 // This mixin application class becomes the type class of the super type of | 2455 // This mixin application class becomes the type class of the super type of |
2462 // the next mixin application class. It is however too early to provide the | 2456 // the next mixin application class. It is however too early to provide the |
2463 // correct super type arguments. We use the raw type for now. | 2457 // correct super type arguments. We use the raw type for now. |
2464 mixin_super_type = Type::New(mixin_app_class, | 2458 mixin_super_type = Type::New(mixin_app_class, |
2465 Object::null_abstract_type_arguments(), | 2459 Object::null_type_arguments(), |
2466 mixin_type.token_pos()); | 2460 mixin_type.token_pos()); |
2467 } | 2461 } |
2468 AbstractType& type_arg = AbstractType::Handle(); | 2462 AbstractType& type_arg = AbstractType::Handle(); |
2469 const TypeArguments& mixin_app_args = | 2463 const TypeArguments& mixin_app_args = |
2470 TypeArguments::Handle(TypeArguments::New(type_args.Length())); | 2464 TypeArguments::Handle(TypeArguments::New(type_args.Length())); |
2471 for (intptr_t i = 0; i < type_args.Length(); i++) { | 2465 for (intptr_t i = 0; i < type_args.Length(); i++) { |
2472 type_arg ^= type_args.At(i); | 2466 type_arg ^= type_args.At(i); |
2473 mixin_app_args.SetTypeAt(i, type_arg); | 2467 mixin_app_args.SetTypeAt(i, type_arg); |
2474 } | 2468 } |
2475 if (FLAG_trace_class_finalization) { | 2469 if (FLAG_trace_class_finalization) { |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2748 prev_error, script, type.token_pos(), | 2742 prev_error, script, type.token_pos(), |
2749 LanguageError::kMalformedType, Heap::kOld, | 2743 LanguageError::kMalformedType, Heap::kOld, |
2750 format, args)); | 2744 format, args)); |
2751 if (FLAG_error_on_bad_type) { | 2745 if (FLAG_error_on_bad_type) { |
2752 ReportError(error); | 2746 ReportError(error); |
2753 } | 2747 } |
2754 type.set_error(error); | 2748 type.set_error(error); |
2755 // Make the type raw, since it may not be possible to | 2749 // Make the type raw, since it may not be possible to |
2756 // properly finalize its type arguments. | 2750 // properly finalize its type arguments. |
2757 type.set_type_class(Class::Handle(Object::dynamic_class())); | 2751 type.set_type_class(Class::Handle(Object::dynamic_class())); |
2758 type.set_arguments(Object::null_abstract_type_arguments()); | 2752 type.set_arguments(Object::null_type_arguments()); |
2759 if (!type.IsFinalized()) { | 2753 if (!type.IsFinalized()) { |
2760 type.SetIsFinalized(); | 2754 type.SetIsFinalized(); |
2761 // Do not canonicalize malformed types, since they may not be resolved. | 2755 // Do not canonicalize malformed types, since they may not be resolved. |
2762 } else { | 2756 } else { |
2763 // The only case where the malformed type was already finalized is when its | 2757 // The only case where the malformed type was already finalized is when its |
2764 // type arguments are not within bounds. In that case, we have a prev_error. | 2758 // type arguments are not within bounds. In that case, we have a prev_error. |
2765 ASSERT(!prev_error.IsNull()); | 2759 ASSERT(!prev_error.IsNull()); |
2766 } | 2760 } |
2767 } | 2761 } |
2768 | 2762 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2896 expected_name ^= String::New("_offset"); | 2890 expected_name ^= String::New("_offset"); |
2897 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2891 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
2898 field ^= fields_array.At(2); | 2892 field ^= fields_array.At(2); |
2899 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2893 ASSERT(field.Offset() == TypedDataView::length_offset()); |
2900 name ^= field.name(); | 2894 name ^= field.name(); |
2901 ASSERT(name.Equals("length")); | 2895 ASSERT(name.Equals("length")); |
2902 #endif | 2896 #endif |
2903 } | 2897 } |
2904 | 2898 |
2905 } // namespace dart | 2899 } // namespace dart |
OLD | NEW |