| Index: runtime/vm/object.cc
|
| ===================================================================
|
| --- runtime/vm/object.cc (revision 41473)
|
| +++ runtime/vm/object.cc (working copy)
|
| @@ -4955,6 +4955,27 @@
|
| }
|
|
|
|
|
| +RawTypeArguments* TypeArguments::CloneUninstantiated(
|
| + const Class& new_owner) const {
|
| + ASSERT(!IsNull());
|
| + ASSERT(IsFinalized());
|
| + ASSERT(!IsInstantiated());
|
| + AbstractType& type = AbstractType::Handle();
|
| + const intptr_t num_types = Length();
|
| + const TypeArguments& clone = TypeArguments::Handle(
|
| + TypeArguments::New(num_types));
|
| + for (intptr_t i = 0; i < num_types; i++) {
|
| + type = TypeAt(i);
|
| + if (!type.IsInstantiated()) {
|
| + type = type.CloneUninstantiated(new_owner);
|
| + }
|
| + clone.SetTypeAt(i, type);
|
| + }
|
| + ASSERT(clone.IsFinalized());
|
| + return clone.raw();
|
| +}
|
| +
|
| +
|
| RawTypeArguments* TypeArguments::Canonicalize(
|
| GrowableObjectArray* trail) const {
|
| if (IsNull() || IsCanonical()) {
|
| @@ -6155,6 +6176,21 @@
|
| clone.set_optimized_instruction_count(0);
|
| clone.set_optimized_call_site_count(0);
|
| clone.set_ic_data_array(Array::Handle());
|
| + if (new_owner.NumTypeParameters() > 0) {
|
| + // Adjust uninstantiated types to refer to type parameters of the new owner.
|
| + AbstractType& type = AbstractType::Handle(clone.result_type());
|
| + type ^= type.CloneUninstantiated(new_owner);
|
| + clone.set_result_type(type);
|
| + const intptr_t num_params = clone.NumParameters();
|
| + Array& array = Array::Handle(clone.parameter_types());
|
| + array ^= Object::Clone(array, Heap::kOld);
|
| + clone.set_parameter_types(array);
|
| + for (intptr_t i = 0; i < num_params; i++) {
|
| + type = clone.ParameterTypeAt(i);
|
| + type ^= type.CloneUninstantiated(new_owner);
|
| + clone.SetParameterTypeAt(i, type);
|
| + }
|
| + }
|
| return clone.raw();
|
| }
|
|
|
| @@ -7027,6 +7063,12 @@
|
| if (!clone.is_static()) {
|
| clone.SetOffset(0);
|
| }
|
| + if (new_owner.NumTypeParameters() > 0) {
|
| + // Adjust the field type to refer to type parameters of the new owner.
|
| + AbstractType& type = AbstractType::Handle(clone.type());
|
| + type ^= type.CloneUninstantiated(new_owner);
|
| + clone.set_type(type);
|
| + }
|
| return clone.raw();
|
| }
|
|
|
| @@ -13823,6 +13865,14 @@
|
| }
|
|
|
|
|
| +RawAbstractType* AbstractType::CloneUninstantiated(
|
| + const Class& new_owner) const {
|
| + // AbstractType is an abstract class.
|
| + UNREACHABLE();
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const {
|
| // AbstractType is an abstract class.
|
| UNREACHABLE();
|
| @@ -14522,12 +14572,27 @@
|
| TypeArguments& type_args = TypeArguments::Handle(arguments());
|
| type_args = type_args.CloneUnfinalized();
|
| const Class& type_cls = Class::Handle(type_class());
|
| - const Type& type = Type::Handle(Type::New(type_cls, type_args, token_pos()));
|
| - type.set_is_resolved();
|
| - return type.raw();
|
| + const Type& clone = Type::Handle(Type::New(type_cls, type_args, token_pos()));
|
| + clone.set_is_resolved();
|
| + return clone.raw();
|
| }
|
|
|
|
|
| +RawAbstractType* Type::CloneUninstantiated(const Class& new_owner) const {
|
| + ASSERT(IsFinalized());
|
| + ASSERT(!IsMalformed());
|
| + if (IsInstantiated()) {
|
| + return raw();
|
| + }
|
| + TypeArguments& type_args = TypeArguments::Handle(arguments());
|
| + type_args = type_args.CloneUninstantiated(new_owner);
|
| + const Class& type_cls = Class::Handle(type_class());
|
| + const Type& clone = Type::Handle(Type::New(type_cls, type_args, token_pos()));
|
| + clone.SetIsFinalized();
|
| + return clone.raw();
|
| +}
|
| +
|
| +
|
| RawAbstractType* Type::Canonicalize(GrowableObjectArray* trail) const {
|
| ASSERT(IsFinalized());
|
| if (IsCanonical() || IsMalformed()) {
|
| @@ -15064,6 +15129,25 @@
|
| }
|
|
|
|
|
| +RawAbstractType* TypeParameter::CloneUninstantiated(
|
| + const Class& new_owner) const {
|
| + ASSERT(IsFinalized());
|
| + AbstractType& upper_bound = AbstractType::Handle(bound());
|
| + upper_bound = upper_bound.CloneUninstantiated(new_owner);
|
| + const Class& old_owner = Class::Handle(parameterized_class());
|
| + const intptr_t new_index = index() +
|
| + new_owner.NumTypeArguments() - old_owner.NumTypeArguments();
|
| + const TypeParameter& clone = TypeParameter::Handle(
|
| + TypeParameter::New(new_owner,
|
| + new_index,
|
| + String::Handle(name()),
|
| + upper_bound,
|
| + token_pos()));
|
| + clone.set_is_finalized();
|
| + return clone.raw();
|
| +}
|
| +
|
| +
|
| intptr_t TypeParameter::Hash() const {
|
| ASSERT(IsFinalized());
|
| uint32_t result = Class::Handle(parameterized_class()).id();
|
| @@ -15284,6 +15368,21 @@
|
| }
|
|
|
|
|
| +RawAbstractType* BoundedType::CloneUninstantiated(
|
| + const Class& new_owner) const {
|
| + if (IsInstantiated()) {
|
| + return raw();
|
| + }
|
| + AbstractType& bounded_type = AbstractType::Handle(type());
|
| + bounded_type = bounded_type.CloneUninstantiated(new_owner);
|
| + AbstractType& upper_bound = AbstractType::Handle(bound());
|
| + upper_bound = upper_bound.CloneUninstantiated(new_owner);
|
| + TypeParameter& type_param = TypeParameter::Handle(type_parameter());
|
| + type_param ^= type_param.CloneUninstantiated(new_owner);
|
| + return BoundedType::New(bounded_type, upper_bound, type_param);
|
| +}
|
| +
|
| +
|
| intptr_t BoundedType::Hash() const {
|
| uint32_t result = AbstractType::Handle(type()).Hash();
|
| // No need to include the hash of the bound, since the bound is defined by the
|
|
|