@@ -7519,7 +7519,7 @@ FunctionPtr Function::GetOutermostFunction() const {
7519
7519
}
7520
7520
7521
7521
FunctionPtr Function::implicit_closure_function() const {
7522
- if (IsClosureFunction() || IsFactory() || IsDispatcherOrImplicitAccessor() ||
7522
+ if (IsClosureFunction() || IsDispatcherOrImplicitAccessor() ||
7523
7523
IsFieldInitializer() || IsFfiTrampoline()) {
7524
7524
return Function::null();
7525
7525
}
@@ -7689,6 +7689,7 @@ void Function::SetForwardingChecks(const Array& checks) const {
7689
7689
// native function: Array[0] = String native name
7690
7690
// Array[1] = Function implicit closure function
7691
7691
// regular function: Function for implicit closure function
7692
+ // constructor, factory: Function for implicit closure function
7692
7693
// ffi trampoline function: FfiTrampolineData (Dart->C)
7693
7694
// dyn inv forwarder: Array[0] = Function target
7694
7695
// Array[1] = TypeArguments default type args
@@ -9160,6 +9161,7 @@ FunctionPtr Function::New(const FunctionType& signature,
9160
9161
FunctionPtr Function::NewClosureFunctionWithKind(UntaggedFunction::Kind kind,
9161
9162
const String& name,
9162
9163
const Function& parent,
9164
+ bool is_static,
9163
9165
TokenPosition token_pos,
9164
9166
const Object& owner) {
9165
9167
ASSERT((kind == UntaggedFunction::kClosureFunction) ||
@@ -9171,7 +9173,7 @@ FunctionPtr Function::NewClosureFunctionWithKind(UntaggedFunction::Kind kind,
9171
9173
: 0));
9172
9174
const Function& result = Function::Handle(
9173
9175
Function::New(signature, name, kind,
9174
- /* is_static = */ parent. is_static() ,
9176
+ /* is_static = */ is_static,
9175
9177
/* is_const = */ false,
9176
9178
/* is_abstract = */ false,
9177
9179
/* is_external = */ false,
@@ -9186,16 +9188,18 @@ FunctionPtr Function::NewClosureFunction(const String& name,
9186
9188
// Use the owner defining the parent function and not the class containing it.
9187
9189
const Object& parent_owner = Object::Handle(parent.RawOwner());
9188
9190
return NewClosureFunctionWithKind(UntaggedFunction::kClosureFunction, name,
9189
- parent, token_pos, parent_owner);
9191
+ parent, parent.is_static(), token_pos,
9192
+ parent_owner);
9190
9193
}
9191
9194
9192
9195
FunctionPtr Function::NewImplicitClosureFunction(const String& name,
9193
9196
const Function& parent,
9194
9197
TokenPosition token_pos) {
9195
9198
// Use the owner defining the parent function and not the class containing it.
9196
9199
const Object& parent_owner = Object::Handle(parent.RawOwner());
9197
- return NewClosureFunctionWithKind(UntaggedFunction::kImplicitClosureFunction,
9198
- name, parent, token_pos, parent_owner);
9200
+ return NewClosureFunctionWithKind(
9201
+ UntaggedFunction::kImplicitClosureFunction, name, parent,
9202
+ parent.is_static() || parent.IsConstructor(), token_pos, parent_owner);
9199
9203
}
9200
9204
9201
9205
bool Function::SafeToClosurize() const {
@@ -9241,7 +9245,7 @@ FunctionPtr Function::ImplicitClosureFunction() const {
9241
9245
zone, NewImplicitClosureFunction(closure_name, *this, token_pos()));
9242
9246
9243
9247
// Set closure function's context scope.
9244
- if (is_static()) {
9248
+ if (is_static() || IsConstructor() ) {
9245
9249
closure_function.set_context_scope(Object::empty_context_scope());
9246
9250
} else {
9247
9251
const ContextScope& context_scope = ContextScope::Handle(
@@ -9252,15 +9256,46 @@ FunctionPtr Function::ImplicitClosureFunction() const {
9252
9256
FunctionType& closure_signature =
9253
9257
FunctionType::Handle(zone, closure_function.signature());
9254
9258
9255
- // Set closure function's type parameters.
9256
- // This function cannot be local, therefore it has no generic parent.
9257
- // Its implicit closure function therefore has no generic parent function
9258
- // either. That is why it is safe to simply copy the type parameters.
9259
- closure_signature.SetTypeParameters(
9260
- TypeParameters::Handle(zone, type_parameters()));
9259
+ // Set closure function's type parameters and result type.
9260
+ if (IsConstructor()) {
9261
+ // Inherit type parameters from owner class.
9262
+ const auto& cls = Class::Handle(zone, Owner());
9263
+ closure_signature.SetTypeParameters(
9264
+ TypeParameters::Handle(zone, cls.type_parameters()));
9265
+ ASSERT(closure_signature.NumTypeParameters() == cls.NumTypeParameters());
9266
+
9267
+ Type& result_type = Type::Handle(zone);
9268
+ const Nullability result_nullability =
9269
+ (nnbd_mode() == NNBDMode::kOptedInLib) ? Nullability::kNonNullable
9270
+ : Nullability::kLegacy;
9271
+ if (cls.IsGeneric()) {
9272
+ TypeArguments& type_args = TypeArguments::Handle(zone);
9273
+ const intptr_t num_type_params = cls.NumTypeParameters();
9274
+ ASSERT(num_type_params > 0);
9275
+ type_args = TypeArguments::New(num_type_params);
9276
+ TypeParameter& type_param = TypeParameter::Handle(zone);
9277
+ for (intptr_t i = 0; i < num_type_params; i++) {
9278
+ type_param = closure_signature.TypeParameterAt(i);
9279
+ type_args.SetTypeAt(i, type_param);
9280
+ }
9281
+ result_type = Type::New(cls, type_args, result_nullability);
9282
+ result_type ^= ClassFinalizer::FinalizeType(result_type);
9283
+ } else {
9284
+ result_type = cls.DeclarationType();
9285
+ result_type = result_type.ToNullability(result_nullability, Heap::kOld);
9286
+ }
9287
+ closure_signature.set_result_type(result_type);
9288
+ } else {
9289
+ // This function cannot be local, therefore it has no generic parent.
9290
+ // Its implicit closure function therefore has no generic parent function
9291
+ // either. That is why it is safe to simply copy the type parameters.
9292
+ closure_signature.SetTypeParameters(
9293
+ TypeParameters::Handle(zone, type_parameters()));
9261
9294
9262
- // Set closure function's result type to this result type.
9263
- closure_signature.set_result_type(AbstractType::Handle(zone, result_type()));
9295
+ // Set closure function's result type to this result type.
9296
+ closure_signature.set_result_type(
9297
+ AbstractType::Handle(zone, result_type()));
9298
+ }
9264
9299
9265
9300
// Set closure function's end token to this end token.
9266
9301
closure_function.set_end_token_pos(end_token_pos());
@@ -9274,8 +9309,9 @@ FunctionPtr Function::ImplicitClosureFunction() const {
9274
9309
// removing the receiver if this is an instance method and adding the closure
9275
9310
// object as first parameter.
9276
9311
const int kClosure = 1;
9277
- const int has_receiver = is_static() ? 0 : 1;
9278
- const int num_fixed_params = kClosure - has_receiver + num_fixed_parameters();
9312
+ const int num_implicit_params = NumImplicitParameters();
9313
+ const int num_fixed_params =
9314
+ kClosure - num_implicit_params + num_fixed_parameters();
9279
9315
const int num_opt_params = NumOptionalParameters();
9280
9316
const bool has_opt_pos_params = HasOptionalPositionalParameters();
9281
9317
const int num_params = num_fixed_params + num_opt_params;
@@ -9294,19 +9330,19 @@ FunctionPtr Function::ImplicitClosureFunction() const {
9294
9330
closure_signature.SetParameterTypeAt(0, param_type);
9295
9331
closure_function.SetParameterNameAt(0, Symbols::ClosureParameter());
9296
9332
for (int i = kClosure; i < num_pos_params; i++) {
9297
- param_type = ParameterTypeAt(has_receiver - kClosure + i);
9333
+ param_type = ParameterTypeAt(num_implicit_params - kClosure + i);
9298
9334
closure_signature.SetParameterTypeAt(i, param_type);
9299
- param_name = ParameterNameAt(has_receiver - kClosure + i);
9335
+ param_name = ParameterNameAt(num_implicit_params - kClosure + i);
9300
9336
// Set the name in the function for positional parameters.
9301
9337
closure_function.SetParameterNameAt(i, param_name);
9302
9338
}
9303
9339
for (int i = num_pos_params; i < num_params; i++) {
9304
- param_type = ParameterTypeAt(has_receiver - kClosure + i);
9340
+ param_type = ParameterTypeAt(num_implicit_params - kClosure + i);
9305
9341
closure_signature.SetParameterTypeAt(i, param_type);
9306
- param_name = ParameterNameAt(has_receiver - kClosure + i);
9342
+ param_name = ParameterNameAt(num_implicit_params - kClosure + i);
9307
9343
// Set the name in the signature for named parameters.
9308
9344
closure_signature.SetParameterNameAt(i, param_name);
9309
- if (IsRequiredAt(has_receiver - kClosure + i)) {
9345
+ if (IsRequiredAt(num_implicit_params - kClosure + i)) {
9310
9346
closure_signature.SetIsRequiredAt(i);
9311
9347
}
9312
9348
}
@@ -9315,7 +9351,7 @@ FunctionPtr Function::ImplicitClosureFunction() const {
9315
9351
9316
9352
// Change covariant parameter types to either Object? for an opted-in implicit
9317
9353
// closure or to Object* for a legacy implicit closure.
9318
- if (!is_static()) {
9354
+ if (!is_static() && !IsConstructor() ) {
9319
9355
BitVector is_covariant(zone, NumParameters());
9320
9356
BitVector is_generic_covariant_impl(zone, NumParameters());
9321
9357
kernel::ReadParameterCovariance(*this, &is_covariant,
@@ -9328,7 +9364,7 @@ FunctionPtr Function::ImplicitClosureFunction() const {
9328
9364
: object_store->legacy_object_type();
9329
9365
ASSERT(object_type.IsCanonical());
9330
9366
for (intptr_t i = kClosure; i < num_params; ++i) {
9331
- const intptr_t original_param_index = has_receiver - kClosure + i;
9367
+ const intptr_t original_param_index = num_implicit_params - kClosure + i;
9332
9368
if (is_covariant.Contains(original_param_index) ||
9333
9369
is_generic_covariant_impl.Contains(original_param_index)) {
9334
9370
closure_signature.SetParameterTypeAt(i, object_type);
@@ -9340,6 +9376,7 @@ FunctionPtr Function::ImplicitClosureFunction() const {
9340
9376
closure_function.SetSignature(closure_signature);
9341
9377
set_implicit_closure_function(closure_function);
9342
9378
ASSERT(closure_function.IsImplicitClosureFunction());
9379
+ ASSERT(HasImplicitClosureFunction());
9343
9380
return closure_function.ptr();
9344
9381
#endif // defined(DART_PRECOMPILED_RUNTIME)
9345
9382
}
0 commit comments