Description
I know this is a long shot.
Dart allows expressions like int
and List<int>
to evaluate to Type
instances representing those types.
That's very convenient when you want to have a type literal, but with dart:mirrors
being deprecated, and Type
objects being useless for most things (all they support is equality), there shouldn't be that many Type
instances. In most cases, a type parameter is a better solution to the problem people are trying to solve using Type
objects. If anything, the syntactic ease of creating Type
objects is encouraging too many uses.
The syntax of type literals has already gotten in the way of using the same syntax for something else. The ClassName.new
tear-off syntax for tearing off the unnamed constructor was only introduced because ClassName
was already taken by the type literal.
With the constuctor tear-off language feature, Dart started allowing List<int>
as a type literal too. That also allows us to define a type alias like typedef typeof<T> = T;
, so that typeof<any type>
can create a Type
object for any type, even those not allowed as type literals.
So, I suggest we introduce a canonical typedef typeof<T> = T;
in the platform libraries, and disallowed any type literal other than typeof<some type>
.
All existing uses of type literals need to be migrated. That can be entirely automatized, but it does require running dart-fix on all the code.
We will be using language versioning, because the typeof
syntax is backwards compatible, and we can start warning and hinting that you should fix the code a few versions earlier than when we actually remove the feature.
All you have to do to migrate will be running dart fix
. (And existing code will keep working at the prior language versions as long as we support those).
This will allow us to:
- Use
ClassName
as the constructor tear-off. - Not have a semi-arbitrary difference between types we allow literals for, and types we don't (functions, records).
- Maybe encourage people to use something else than
Type
objects. If you have your ownclass Type<T>
to represent types, it's shorter to write thantypeof<T>
, and can have more features. - Give better error messages when people use a type name incorrectly (classical example:
if (T is int)
to check if a type variable is some type, it instead gives no error and is always false).
Activity
marcotas commentedon Aug 10, 2022
@lrhn, I'm building a server framework in pure dart to serve all front-end flavours (flutter, tailwindcss, vue, react, svelt etc). So the framework trust on mirrors to inject depencies based on types.
For example if you define a controller like below, you will have the
request
andrepository
objects injected into your controller method automatically based on mirrors that recursively tries to resolve all the dependencies if you didn't register them in the service container.I don't want to change this behavior but I'd like to know/understand how I should be able to do this without mirrors. What would be the best or official way to use reflections without mirrors?
(Sorry If this question was massively asked dart team and if I'm missing something here. I'm new to dart language but I love it)
I appreciate any help or suggestions on this. Thank you
Levi-Lesches commentedon Aug 10, 2022
dart:mirrors
allows you to introspect the code running, meaning its reflection is all done at runtime. The alternative is code generation, in which you use the Analyzer to inspect code before it's compiled and add your own classes/functions/etc. to it. I'm not sure how your project works, but you might be able to convert it to code generation instead of reflection. With this approach, you would do the same type of analysis as you are now but with variables known at compile-time, and then generate code to do what you want.In this case, you may be interested in the up-and-coming macros feature, which makes code generation much easier to work with and officially supported by the language.
is
. #2137X is Enum
reportingfalse
forenum X
dart-lang/sdk#52824