-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
mixin on a ClassMirror of a class which is the result of a mixin application of the form S with M doesn't work #33240
Comments
The mixed-in type of a mixin application is not available as it is removed while mixins are de-sugared by kernel mixin transformation. This transformation erases mixed-in type and adds it into the list of interfaces. In order to correctly implement dart:mirrors, CFE should leave some information about original mixed-in type and original list of interfaces in Dart sources, or at least inform VM about performed transformation. While keeping original mixed-in type and original list of interfaces is a cleaner solution, it will increase size of kernel binaries. Instead of adding those fields, we can introduce 'isTransformedMixinApplication' flag and propagate it all the way to the dart:mirrors implementation. Using this flag, dart:mirrrors implementation can 'undo' the changes in mixed-in type and superinterfaces. This solution is implemented here: https://dart-review.googlesource.com/c/sdk/+/56721. @kmillikin please take a look. Can you suggest a better way of representing such information in kernel? |
Just a quick comment because it's late. That was exactly the intent of isSyntheticMixinApplication (https://codereview.chromium.org/2982373002) but it turns out that the implementation was incomplete. The flag was not documented in binary.md and was not set in all cases. For classes marked as synthetic mixins, you should be able to rely on the superclass being the superclass and the mixed-in class being the only implemented interface. Is there any reason that the VM needs to distinguish between "synthetic mixins" and "transformed mixins"? If not, I think a change like this should be sufficient on the Kernel side:
(We should probably consider updating the text format but that requires rebasing tests.) |
Thank you for quick feedback! We need a flag which covers mixin applications which were transformed to normal classes, including anonymous mixin applications and named mixin applications. Synthetic mixin flag was not set for named mixin applications (mixin aliases): sdk/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart Lines 452 to 453 in 57d2563
I was afraid to change the semantics of the isSyntheticMixinImplementation flag as other backends might not expect that: sdk/pkg/compiler/lib/src/kernel/env.dart Line 300 in 57d2563
Do you think it's a good idea to set 'isSyntheticMixinImplementation' for named mixin applications even though they are present in sources and not really synthetic? AFAICT, currently VM doesn't use synthetic mixin application flag, but it could be need in future. For example, dart:mirrors implementation distinguishes between named and anonymous mixin applications for Dart 1 mixins, and eventually we might need this for desugared Dart 2 mixins as well. Also, named mixin applications may have implemented interfaces, so mixed-in type is not the only type in their lists of interfaces. Please advise how to proceed. |
The VM is the only backend that uses the mixin elimination transformation. So the question is: does the VM need to distinguish between classes that were originally named or anonymous mixin applications. If not, we don't need a separate flag. Dart2js only sees named (never anonymous) mixin applications. If it sees the flag on a named mixin application it knows that it was originally anonymous. The VM only sees normal classes (never mixin applications). If it sees the flag on a normal class it knows it was originally a mixin application. Is that sufficient? (The name is not great, but I can't think of anything that's much better so I'm inclined to just leave it for now.) You're right about named mixing being able to implement interfaces. That means you can rely on there being at least one implementedType and implementedTypes.last is the original mixed-in type. |
To implement dart:mirrors correctly, a backend like the VM needs to know that a class was originally a mixin application. Use the `isSyntheticMixinImplementation` flag which was already there and ignored by the VM. Now the property is: - if `isSyntheticMixinImplementation` is set on a class with a mixed-in type, then it was originally an anonymous mixin application - if `isSyntheticMixinImplementation` is set on a normal class then it was originally a mixin application of some kind and the mixed-in type can be found as the last impelemented type Bug: #33240 Change-Id: I004adc6bfe08e583efba8e511076a6c603c0c687 Reviewed-on: https://dart-review.googlesource.com/56760 Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Kevin Millikin <kmillikin@google.com>
The ClassMirror of a class which is the result of mixing application of the form S with M returns a class mirror of the reflectee and not the mixin.
The code below -
prints
"ClassMirror on 'Mixin'" when run with Dart 1 and
"ClassMirror on 'MixinApplication'" with Dart 2.
Cause - The mixin_ field in the RawClass object in the VM is not being correctly populated,
The kernel file does not have this information to be able to populate this field correctly when loading the kernel file in the VM.
The text was updated successfully, but these errors were encountered: