-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Re-think augmenting constructor bodies #3554
Comments
To instrument disposables using macros, I need to augment constructors: flutter/flutter#137435 For now, experimenting with empty-body constructors. |
After fix for error reporting I started seeing the error. It is "Unsupported operation: Augmenting existing constructor bodies is not allowed.". It blocks the prototyping for me. Any chance at least empty constructors can be supported soon? I use |
The Freezed macro tries to generate an augmented constructor at the moment. I think that's a good scenario to test against. IMO we should treat augmented constructors similar to a class Base {
Base({bool? flag});
}
class Foo extends Base {
Foo({this.a})
: assert(a >= 0),
super(flag: true);
int? a;
}
augment class Foo {
augment Foo({int? a})
: _newField = ...,
assert(...),
augmented(a: a * 2);
final int _newField;
} |
It looks like the analyzer does work here, but the CFE does not. It looks like it must be reporting |
The problem with that is that invoking the augmenting constructor means re-evaluating the parameter list, which may contain initializing formals. And should also include evaluating the initializer list in that patientrettet scope, an initializer list which has already been evaluated before we got to executing bodies. And the already executed initializer list could have created a closure closing over the original parameter variables. The augmented body may even assume that an instance variable has been initialized with a closure that closes over a parameter, and that it's the same variable that it has available in the body. My suggestion is to have |
#3737 should also resolve the specification with regards to this issue, which should in turn unblock the implementations. |
@jakemac53 The CFE doesn't support constructor augmentation yet (only replacing an external constructor with a concrete, as used for patching), so you will see weirdness here. |
@johnniwinther , what is 'external constructor'? |
An external constructor is a constructor with the
Dart backends provide implementation for such declarations by the "patching mechanism" which is similar to augmentations. For instance
where The patching mechanism predates the augmentation libraries feature but because of their similarity I've built the support for augmentations on the patching implementation. In time making patching just a restricted variant of augmentation. Therefore the current state of augmentations reflect that; I've have not added support for augmenting constructors yet, but it has inherited the functionality already present in patching. |
We realized today that in particular
augmented
expressions are extremely weird for constructors. You do not want to re-run the original initializer list for instance. We could say that you just always invoke it with zero parameters, and it runs the original body with whatever the current scope is, but that also feels very weird.We could also say that
augmented
is banned in augmenting constructor bodies, since the semantics are just too difficult to specify.We could also just say the original constructor body is implicitly called, and specify the ordering in which that happens.
Or, we can say you can only add a constructor body where none existed previously, but cannot replace an existing one.
The text was updated successfully, but these errors were encountered: