Skip to content
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

Macros: ergonomics of type checking (StaticType) in the current API #3606

Open
GregoryConrad opened this issue Feb 2, 2024 · 2 comments
Open
Labels
request Requests to resolve a particular developer problem

Comments

@GregoryConrad
Copy link

GregoryConrad commented Feb 2, 2024

See this comment from some time ago for a little context. CC @jakemac53

I was recently trying to create a macro and realized it is pretty painful (I ended giving up in the moment) on checking whether some TypeAnnotation is the same type as a type defined in an external package. I ended up using String equality on the types' names, which is obviously incorrect.

Since resolving a type via its library's Uri is not the safest option (and is @Deprecated because of that), perhaps a better option would be to repurpose Type (see #2393) so that it can be used to reference a type's StaticType. A compelling API could look something like the following:

import 'packages:flutter/widgets.dart';

builder.resolve(myTypeAnnotation.code).isExactly(Widget.staticType) // perhaps backwards compatible
// or even:
builder.resolve(myTypeAnnotation.code).isExactly(Widget) // maybe not backwards compatible, but nicer API

This:

  1. Solves the entire "is this type transitively included" problem, since it must be imported in the macro itself in order to reference the type (Widget above)
  2. Improves the ergonomics of type-checking tenfold, and doesn't rely on a handwritten Uri
@GregoryConrad GregoryConrad added the request Requests to resolve a particular developer problem label Feb 2, 2024
@GregoryConrad
Copy link
Author

GregoryConrad commented Feb 4, 2024

Something similar would also be extremely helpful in DeclarationCode.fromParts; take:

      [
        'Widget',
        ' build(',
        ...['BuildContext', ' ', contextName, ', '],
        ') => ',
        ...[functionName, '(', functionArgs, ');'],
      ],

The above would be much more elegant/error-free with (an example):

      [
        Widget.code,
        ' build(',
        ...[BuildContext.code, ' ', contextName, ', '],
        ') => ',
        ...[functionName, '(', functionArgs, ');'],
      ],

When you start to consider all of the types generated code will need to reference, this adds up really quick. Also, if there's no API that makes referencing external types easy, I'd bet many folks would resort to strings directly, which comes with its own bag of problems.

@jakemac53
Copy link
Contributor

The current API is definitely quite verbose, no argument from me there.

We can't use Type instances directly, it just isn't feasible to do, because those types you are referencing do not exist in the compiler/analyzer isolate, only in the macro isolate (most likely at least).

My personal favorite proposal so far relating to this is reflected imports. That gives you a way of doing something similar to a normal import, but it gives you identifiers to the references from that library instead of a regular reference.

That doesn't fully solve all the verbosity, getting a StaticType is still a bit cumbersome, but it does solve part of it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
request Requests to resolve a particular developer problem
Projects
None yet
Development

No branches or pull requests

2 participants