| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index d4642901f643b2b8fcdf2abf92961a01b87df277..17db59f3253d45a396459a2b1715f6140a850f6e 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -5731,6 +5731,44 @@ RawType* Function::ExistingSignatureType() const {
|
| }
|
|
|
|
|
| +RawFunction* Function::CanonicalSignatureFunction(TrailPtr trail) const {
|
| + ASSERT(!IsSignatureFunction());
|
| + Zone* zone = Thread::Current()->zone();
|
| + Function& parent = Function::Handle(zone, parent_function());
|
| + if (!parent.IsNull() && !parent.IsSignatureFunction()) {
|
| + // Make sure the parent function is also a signature function.
|
| + parent = parent.CanonicalSignatureFunction(trail);
|
| + }
|
| + const Class& owner = Class::Handle(zone, Owner());
|
| + const Function& sig_fun = Function::Handle(
|
| + zone,
|
| + Function::NewSignatureFunction(owner, parent, TokenPosition::kNoSource));
|
| + // In case of a generic function, the function type parameters in the
|
| + // signature will still refer to the original function. This should not
|
| + // be a problem, since once finalized the indices will be identical.
|
| + sig_fun.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
|
| + ASSERT(HasGenericParent() == sig_fun.HasGenericParent());
|
| + ASSERT(IsGeneric() == sig_fun.IsGeneric());
|
| + AbstractType& type = AbstractType::Handle(zone);
|
| + type = result_type();
|
| + type = type.Canonicalize(trail);
|
| + sig_fun.set_result_type(type);
|
| + const intptr_t num_params = NumParameters();
|
| + sig_fun.set_num_fixed_parameters(num_fixed_parameters());
|
| + sig_fun.SetNumOptionalParameters(NumOptionalParameters(),
|
| + HasOptionalPositionalParameters());
|
| + sig_fun.set_parameter_types(
|
| + Array::Handle(Array::New(num_params, Heap::kOld)));
|
| + for (intptr_t i = 0; i < num_params; i++) {
|
| + type = ParameterTypeAt(i);
|
| + type = type.Canonicalize(trail);
|
| + sig_fun.SetParameterTypeAt(i, type);
|
| + }
|
| + sig_fun.set_parameter_names(Array::Handle(zone, parameter_names()));
|
| + return sig_fun.raw();
|
| +}
|
| +
|
| +
|
| RawType* Function::SignatureType() const {
|
| Type& type = Type::Handle(ExistingSignatureType());
|
| if (type.IsNull()) {
|
| @@ -17716,35 +17754,9 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
|
| // In case of a function type, replace the actual function by a signature
|
| // function.
|
| if (IsFunctionType()) {
|
| - const Function& fun = Function::Handle(zone, signature());
|
| - if (!fun.IsSignatureFunction()) {
|
| - // In case of a generic function, the function type parameters in the
|
| - // signature will still refer to the original function. This should not
|
| - // be a problem, since they are finalized and the indices remain
|
| - // unchanged.
|
| - const Function& parent = Function::Handle(zone, fun.parent_function());
|
| - Function& sig_fun =
|
| - Function::Handle(zone, Function::NewSignatureFunction(
|
| - cls, parent, TokenPosition::kNoSource));
|
| - sig_fun.set_type_parameters(
|
| - TypeArguments::Handle(zone, fun.type_parameters()));
|
| - ASSERT(fun.HasGenericParent() == sig_fun.HasGenericParent());
|
| - ASSERT(fun.IsGeneric() == sig_fun.IsGeneric());
|
| - type = fun.result_type();
|
| - type = type.Canonicalize(trail);
|
| - sig_fun.set_result_type(type);
|
| - const intptr_t num_params = fun.NumParameters();
|
| - sig_fun.set_num_fixed_parameters(fun.num_fixed_parameters());
|
| - sig_fun.SetNumOptionalParameters(fun.NumOptionalParameters(),
|
| - fun.HasOptionalPositionalParameters());
|
| - sig_fun.set_parameter_types(
|
| - Array::Handle(Array::New(num_params, Heap::kOld)));
|
| - for (intptr_t i = 0; i < num_params; i++) {
|
| - type = fun.ParameterTypeAt(i);
|
| - type = type.Canonicalize(trail);
|
| - sig_fun.SetParameterTypeAt(i, type);
|
| - }
|
| - sig_fun.set_parameter_names(Array::Handle(zone, fun.parameter_names()));
|
| + Function& sig_fun = Function::Handle(zone, signature());
|
| + if (!sig_fun.IsSignatureFunction()) {
|
| + sig_fun = sig_fun.CanonicalSignatureFunction(trail);
|
| set_signature(sig_fun);
|
| // Note that the signature type of the signature function may be
|
| // different than the type being canonicalized.
|
|
|