| Index: runtime/vm/class_finalizer.cc
|
| ===================================================================
|
| --- runtime/vm/class_finalizer.cc (revision 3631)
|
| +++ runtime/vm/class_finalizer.cc (working copy)
|
| @@ -271,7 +271,7 @@
|
| const Script& script = Script::Handle(cls.script());
|
| ReportError(script, unresolved_class.token_index(),
|
| "cannot resolve library prefix '%s' from '%s'.\n",
|
| - String::Handle(unresolved_class.Name()).ToCString(),
|
| + qualifier.ToCString(),
|
| String::Handle(cls.Name()).ToCString());
|
| }
|
| lib = lib_prefix.library();
|
| @@ -378,45 +378,77 @@
|
| factory_name.ToCString());
|
| }
|
| interface.set_factory_class(factory_class);
|
| - // Check that the type parameter lists are identical.
|
| + ResolveAndFinalizeUpperBounds(factory_class);
|
| + const intptr_t num_factory_type_params = factory_class.NumTypeParameters();
|
| const Class& factory_signature_class = Class::Handle(
|
| unresolved_factory_class.factory_signature_class());
|
| ASSERT(!factory_signature_class.IsNull());
|
| - ResolveAndFinalizeUpperBounds(factory_class);
|
| - ResolveAndFinalizeUpperBounds(factory_signature_class);
|
| - String& expected_type_name = String::Handle();
|
| - String& actual_type_name = String::Handle();
|
| - AbstractType& expected_type_extends = AbstractType::Handle();
|
| - AbstractType& actual_type_extends = AbstractType::Handle();
|
| - const Array& expected_type_names =
|
| - Array::Handle(factory_signature_class.type_parameters());
|
| - const Array& actual_type_names =
|
| + const intptr_t num_default_type_params =
|
| + factory_signature_class.NumTypeParameters();
|
| + // If a type parameter list is included in the default factory clause (it
|
| + // can be omitted), verify that it matches the list of type parameters of
|
| + // the factory class in number, names, and bounds.
|
| + if (num_default_type_params > 0) {
|
| + ResolveAndFinalizeUpperBounds(factory_signature_class);
|
| + String& expected_type_name = String::Handle();
|
| + String& actual_type_name = String::Handle();
|
| + AbstractType& expected_type_extends = AbstractType::Handle();
|
| + AbstractType& actual_type_extends = AbstractType::Handle();
|
| + const Array& expected_type_names =
|
| + Array::Handle(factory_signature_class.type_parameters());
|
| + const Array& actual_type_names =
|
| + Array::Handle(factory_class.type_parameters());
|
| + const TypeArguments& expected_extends_array =
|
| + TypeArguments::Handle(factory_signature_class.type_parameter_extends());
|
| + const TypeArguments& actual_extends_array =
|
| + TypeArguments::Handle(factory_class.type_parameter_extends());
|
| + bool mismatch = num_factory_type_params != num_default_type_params;
|
| + for (intptr_t i = 0; !mismatch && (i < num_default_type_params); i++) {
|
| + expected_type_name ^= expected_type_names.At(i);
|
| + actual_type_name ^= actual_type_names.At(i);
|
| + expected_type_extends = expected_extends_array.TypeAt(i);
|
| + actual_type_extends = actual_extends_array.TypeAt(i);
|
| + if (!expected_type_name.Equals(actual_type_name) ||
|
| + !expected_type_extends.Equals(actual_type_extends)) {
|
| + mismatch = true;
|
| + }
|
| + }
|
| + if (mismatch) {
|
| + const String& interface_name = String::Handle(interface.Name());
|
| + const String& factory_name = String::Handle(factory_class.Name());
|
| + const Script& script = Script::Handle(interface.script());
|
| + ReportError(script, unresolved_factory_class.token_index(),
|
| + "mismatch in number, names, or bounds of type parameters "
|
| + "between default clause of interface '%s' and actual factory "
|
| + "class '%s'.\n",
|
| + interface_name.ToCString(),
|
| + factory_name.ToCString());
|
| + }
|
| + }
|
| + // Verify that the type parameters of the factory class and of the interface
|
| + // have identical names.
|
| + String& interface_type_param_name = String::Handle();
|
| + String& factory_type_param_name = String::Handle();
|
| + const Array& interface_type_param_names =
|
| + Array::Handle(interface.type_parameters());
|
| + const Array& factory_type_param_names =
|
| Array::Handle(factory_class.type_parameters());
|
| - const TypeArguments& expected_extends_array =
|
| - TypeArguments::Handle(factory_signature_class.type_parameter_extends());
|
| - const TypeArguments& actual_extends_array =
|
| - TypeArguments::Handle(factory_class.type_parameter_extends());
|
| - const intptr_t num_type_params = factory_signature_class.NumTypeParameters();
|
| - bool mismatch = factory_class.NumTypeParameters() != num_type_params;
|
| - for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) {
|
| - expected_type_name ^= expected_type_names.At(i);
|
| - actual_type_name ^= actual_type_names.At(i);
|
| - expected_type_extends = expected_extends_array.TypeAt(i);
|
| - actual_type_extends = actual_extends_array.TypeAt(i);
|
| - if (!expected_type_name.Equals(actual_type_name) ||
|
| - !expected_type_extends.Equals(actual_type_extends)) {
|
| + const intptr_t num_interface_type_params = interface.NumTypeParameters();
|
| + bool mismatch = num_interface_type_params != num_factory_type_params;
|
| + for (intptr_t i = 0; !mismatch && (i < num_factory_type_params); i++) {
|
| + interface_type_param_name ^= interface_type_param_names.At(i);
|
| + factory_type_param_name ^= factory_type_param_names.At(i);
|
| + if (!interface_type_param_name.Equals(factory_type_param_name)) {
|
| mismatch = true;
|
| }
|
| }
|
| - // The list of type parameters in the default factory clause can be omitted.
|
| - if (mismatch && (num_type_params > 0)) {
|
| + if (mismatch) {
|
| const String& interface_name = String::Handle(interface.Name());
|
| const String& factory_name = String::Handle(factory_class.Name());
|
| const Script& script = Script::Handle(interface.script());
|
| ReportError(script, unresolved_factory_class.token_index(),
|
| - "mismatch in number, names, or bounds of type parameters "
|
| - "between default clause of interface '%s' and actual factory "
|
| - "class '%s'.\n",
|
| + "mismatch in number or names of type parameters between "
|
| + "interface '%s' and default factory class '%s'.\n",
|
| interface_name.ToCString(),
|
| factory_name.ToCString());
|
| }
|
|
|