| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 unresolved_factory_class.factory_signature_class()); | 427 unresolved_factory_class.factory_signature_class()); |
| 428 ASSERT(!factory_signature_class.IsNull()); | 428 ASSERT(!factory_signature_class.IsNull()); |
| 429 // If a type parameter list is included in the default factory clause (it | 429 // If a type parameter list is included in the default factory clause (it |
| 430 // can be omitted), verify that it matches the list of type parameters of | 430 // can be omitted), verify that it matches the list of type parameters of |
| 431 // the factory class in number, names, and bounds. | 431 // the factory class in number, names, and bounds. |
| 432 if (factory_signature_class.NumTypeParameters() > 0) { | 432 if (factory_signature_class.NumTypeParameters() > 0) { |
| 433 const TypeArguments& expected_type_parameters = | 433 const TypeArguments& expected_type_parameters = |
| 434 TypeArguments::Handle(factory_signature_class.type_parameters()); | 434 TypeArguments::Handle(factory_signature_class.type_parameters()); |
| 435 const TypeArguments& actual_type_parameters = | 435 const TypeArguments& actual_type_parameters = |
| 436 TypeArguments::Handle(factory_class.type_parameters()); | 436 TypeArguments::Handle(factory_class.type_parameters()); |
| 437 const TypeArguments& expected_type_parameter_bounds = | 437 const bool check_type_parameter_bounds = true; |
| 438 TypeArguments::Handle(factory_signature_class.type_parameter_bounds()); | |
| 439 const TypeArguments& actual_type_parameter_bounds = | |
| 440 TypeArguments::Handle(factory_class.type_parameter_bounds()); | |
| 441 if (!AbstractTypeArguments::AreIdentical(expected_type_parameters, | 438 if (!AbstractTypeArguments::AreIdentical(expected_type_parameters, |
| 442 actual_type_parameters) || | 439 actual_type_parameters, |
| 443 !AbstractTypeArguments::AreIdentical(expected_type_parameter_bounds, | 440 check_type_parameter_bounds)) { |
| 444 actual_type_parameter_bounds)) { | |
| 445 const String& interface_name = String::Handle(interface.Name()); | 441 const String& interface_name = String::Handle(interface.Name()); |
| 446 const String& factory_name = String::Handle(factory_class.Name()); | 442 const String& factory_name = String::Handle(factory_class.Name()); |
| 447 const Script& script = Script::Handle(interface.script()); | 443 const Script& script = Script::Handle(interface.script()); |
| 448 ReportError(script, unresolved_factory_class.token_pos(), | 444 ReportError(script, unresolved_factory_class.token_pos(), |
| 449 "mismatch in number, names, or bounds of type parameters " | 445 "mismatch in number, names, or bounds of type parameters " |
| 450 "between default clause of interface '%s' and actual factory " | 446 "between default clause of interface '%s' and actual factory " |
| 451 "class '%s'", | 447 "class '%s'", |
| 452 interface_name.ToCString(), | 448 interface_name.ToCString(), |
| 453 factory_name.ToCString()); | 449 factory_name.ToCString()); |
| 454 } | 450 } |
| 455 } | 451 } |
| 456 // Verify that the type parameters of the factory class and of the interface | 452 // Verify that the type parameters of the factory class and of the interface |
| 457 // have identical names. | 453 // have identical names, but not necessarily identical bounds. |
| 458 const TypeArguments& interface_type_parameters = | 454 const TypeArguments& interface_type_parameters = |
| 459 TypeArguments::Handle(interface.type_parameters()); | 455 TypeArguments::Handle(interface.type_parameters()); |
| 460 const TypeArguments& factory_type_parameters = | 456 const TypeArguments& factory_type_parameters = |
| 461 TypeArguments::Handle(factory_class.type_parameters()); | 457 TypeArguments::Handle(factory_class.type_parameters()); |
| 458 const bool check_type_parameter_bounds = false; |
| 462 if (!AbstractTypeArguments::AreIdentical(interface_type_parameters, | 459 if (!AbstractTypeArguments::AreIdentical(interface_type_parameters, |
| 463 factory_type_parameters)) { | 460 factory_type_parameters, |
| 461 check_type_parameter_bounds)) { |
| 464 const String& interface_name = String::Handle(interface.Name()); | 462 const String& interface_name = String::Handle(interface.Name()); |
| 465 const String& factory_name = String::Handle(factory_class.Name()); | 463 const String& factory_name = String::Handle(factory_class.Name()); |
| 466 const Script& script = Script::Handle(interface.script()); | 464 const Script& script = Script::Handle(interface.script()); |
| 467 ReportError(script, unresolved_factory_class.token_pos(), | 465 ReportError(script, unresolved_factory_class.token_pos(), |
| 468 "mismatch in number or names of type parameters between " | 466 "mismatch in number or names of type parameters between " |
| 469 "interface '%s' and default factory class '%s'", | 467 "interface '%s' and default factory class '%s'", |
| 470 interface_name.ToCString(), | 468 interface_name.ToCString(), |
| 471 factory_name.ToCString()); | 469 factory_name.ToCString()); |
| 472 } | 470 } |
| 473 } | 471 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 const Class& parameterized_class = | 629 const Class& parameterized_class = |
| 632 Class::Handle(type_parameter.parameterized_class()); | 630 Class::Handle(type_parameter.parameterized_class()); |
| 633 ASSERT(!parameterized_class.IsNull()); | 631 ASSERT(!parameterized_class.IsNull()); |
| 634 // The index must reflect the position of this type parameter in the type | 632 // The index must reflect the position of this type parameter in the type |
| 635 // arguments vector of its parameterized class. The offset to add is the | 633 // arguments vector of its parameterized class. The offset to add is the |
| 636 // number of type arguments in the super type, which is equal to the | 634 // number of type arguments in the super type, which is equal to the |
| 637 // difference in number of type arguments and type parameters of the | 635 // difference in number of type arguments and type parameters of the |
| 638 // parameterized class. | 636 // parameterized class. |
| 639 const intptr_t offset = parameterized_class.NumTypeArguments() - | 637 const intptr_t offset = parameterized_class.NumTypeArguments() - |
| 640 parameterized_class.NumTypeParameters(); | 638 parameterized_class.NumTypeParameters(); |
| 641 type_parameter.set_index(type_parameter.Index() + offset); | 639 type_parameter.set_index(type_parameter.index() + offset); |
| 642 type_parameter.set_is_finalized(); | 640 type_parameter.set_is_finalized(); |
| 643 // We do not canonicalize type parameters. | 641 // We do not canonicalize type parameters. |
| 644 return type_parameter.raw(); | 642 return type_parameter.raw(); |
| 645 } | 643 } |
| 646 | 644 |
| 647 // At this point, we can only have a parameterized_type. | 645 // At this point, we can only have a parameterized_type. |
| 648 Type& parameterized_type = Type::Handle(); | 646 Type& parameterized_type = Type::Handle(); |
| 649 parameterized_type ^= type.raw(); | 647 parameterized_type ^= type.raw(); |
| 650 | 648 |
| 651 if (parameterized_type.IsBeingFinalized()) { | 649 if (parameterized_type.IsBeingFinalized()) { |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 } | 895 } |
| 898 super_class = super_class.SuperClass(); | 896 super_class = super_class.SuperClass(); |
| 899 } | 897 } |
| 900 return Class::null(); | 898 return Class::null(); |
| 901 } | 899 } |
| 902 | 900 |
| 903 | 901 |
| 904 // Resolve and finalize the upper bounds of the type parameters of class cls. | 902 // Resolve and finalize the upper bounds of the type parameters of class cls. |
| 905 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { | 903 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { |
| 906 const intptr_t num_type_params = cls.NumTypeParameters(); | 904 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 905 TypeParameter& type_param = TypeParameter::Handle(); |
| 907 AbstractType& bound = AbstractType::Handle(); | 906 AbstractType& bound = AbstractType::Handle(); |
| 908 const AbstractTypeArguments& bounds = | 907 const AbstractTypeArguments& type_params = |
| 909 AbstractTypeArguments::Handle(cls.type_parameter_bounds()); | 908 AbstractTypeArguments::Handle(cls.type_parameters()); |
| 910 ASSERT((bounds.IsNull() && (num_type_params == 0)) || | 909 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
| 911 (bounds.Length() == num_type_params)); | 910 (type_params.Length() == num_type_params)); |
| 912 for (intptr_t i = 0; i < num_type_params; i++) { | 911 for (intptr_t i = 0; i < num_type_params; i++) { |
| 913 bound = bounds.TypeAt(i); | 912 type_param ^= type_params.TypeAt(i); |
| 913 bound = type_param.bound(); |
| 914 if (bound.IsFinalized()) { | 914 if (bound.IsFinalized()) { |
| 915 continue; | 915 continue; |
| 916 } | 916 } |
| 917 ResolveType(cls, bound, kFinalize); | 917 ResolveType(cls, bound, kFinalize); |
| 918 bound = FinalizeType(cls, bound, kFinalize); | 918 bound = FinalizeType(cls, bound, kFinalize); |
| 919 bounds.SetTypeAt(i, bound); | 919 type_param.set_bound(bound); |
| 920 } | 920 } |
| 921 } | 921 } |
| 922 | 922 |
| 923 | 923 |
| 924 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 924 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
| 925 // Note that getters and setters are explicitly listed as such in the list of | 925 // Note that getters and setters are explicitly listed as such in the list of |
| 926 // functions of a class, so we do not need to consider fields as implicitly | 926 // functions of a class, so we do not need to consider fields as implicitly |
| 927 // generating getters and setters. | 927 // generating getters and setters. |
| 928 // The only compile errors we report are therefore: | 928 // The only compile errors we report are therefore: |
| 929 // - a getter having the same name as a method (but not a getter) in a super | 929 // - a getter having the same name as a method (but not a getter) in a super |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1501 void ClassFinalizer::ReportError(const char* format, ...) { | 1501 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1502 va_list args; | 1502 va_list args; |
| 1503 va_start(args, format); | 1503 va_start(args, format); |
| 1504 const Error& error = Error::Handle( | 1504 const Error& error = Error::Handle( |
| 1505 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1505 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1506 va_end(args); | 1506 va_end(args); |
| 1507 ReportError(error); | 1507 ReportError(error); |
| 1508 } | 1508 } |
| 1509 | 1509 |
| 1510 } // namespace dart | 1510 } // namespace dart |
| OLD | NEW |