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

Should macros be able to generate source-map? #13

Open
rrousselGit opened this issue Jul 3, 2021 · 5 comments
Open

Should macros be able to generate source-map? #13

rrousselGit opened this issue Jul 3, 2021 · 5 comments

Comments

@rrousselGit
Copy link
Contributor

rrousselGit commented Jul 3, 2021

Related to #9

Whether macros are able to rewrite a function of not, some macros will likely cause breakpoints to stop working.

For example, one macro I would like to write is, a user would define:

@functionalWidget
Widget _$MyApp(BuildContext context) {
  @state int count = Random().nextInt(999);
  
  return Column(
    children: [
      Text('Counter $count'),
      Button(onPressed: () => count++),
    ],
  );
}

then this would generate:

class MyApp extends StatefulWidget {
  const MyApp({Key? key}): super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late int count;

  @override
  void initState() {
    super.initState();
    count = Random().nextInt(999);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Counter $count'),
        Button(onPressed: () => setState(() => count++)),
      ],
    );
  }
}

The problem is, _$MyApp is unused. If a user defines breakpoints inside _$MyApp, nothing will happen.

We could expect users to add breakpoints inside the generated code, but this is a very bad user experience. The generated code should be invisible to them, and will likely be a lot less readable than what they defined.

If macros could generate source-maps, this would allow breakpoints placed in _$MyApp to act as if they were placed in the matching code within _MyAppState.

@jakemac53
Copy link
Owner

In general it is expected that users will need to set breakpoints in generated code - for instance where the code is generated not from existing code but from the existing members of the class (serialization, constructors, hashCode, ==, etc).

We are working with the analyzer and IDE plugin teams still to try and figure out what the UX around this should look like.

There are other issues with the example you are proposing here though:

  • Dart doesn't allow statement level annotations
  • The macro apis don't enable copying of code like this from one declaration to another
  • Access to the implementation code, even if added, wouldn't be available until after the definition phase (maybe it would be a 4th phase)? But you wouldn't be able to add new declarations (classes in this case) in that phase.

Annotations on statements could possibly be enabled, but there are issues with allowing access to annotations at all from macros that we are currently looking into anyways.

As far as the latter part goes I don't see how that would really fit in with the general mechanisms we have. It would cause ordering problems and many other issues, and we aren't targeting this as a use case. I think this issue you have brought up is actually good reason for why we aren't targeting this use case though. It adds a lot of potential complications beyond just debugging.

We do want to target widget (and specifically stateful widget) boilerplate, but it is a bit difficult to do because of the multiple classes each with their own fields.

@rrousselGit
Copy link
Contributor Author

In general it is expected that users will need to set breakpoints in generated code

Then this isn't solving the root issue of code-generation: bad developer experience.

Generated code often has a poor readability. Expecting users to inspect it to debug their code sound problematic.

I think this issue you have brought up is actually good reason for why we aren't targeting this use case though. It adds a lot of potential complications beyond just debugging.

But #9 offers other use-cases that were considered valid, that would break breakpoints. The @action/@debounce change the function body

@jakemac53
Copy link
Owner

Then this isn't solving the root issue of code-generation: bad developer experience.

It does address a variety of other key developer issues with existing codegen.

But #9 offers other use-cases that were considered valid, that would break breakpoints. The @action/@debounce change the function body

In this case given the current apis exposed the compilers themselves could do the mapping.

@rrousselGit
Copy link
Contributor Author

rrousselGit commented Jul 7, 2021

It does address a variety of other key developer issues with existing codegen.

It seem to focus on issues from the consumer side but ignore issues encountered by package authors

For authors, the biggest pain point IMO is the lack of flexibility of codegen. Authors have to work around the language by proposing a less ideal API to implement their features

As a matter of fact, hooks would not be possible to implement using the current macro proposal and the common complaints with functional_widget/freezed won't be covered either.

@rrousselGit
Copy link
Contributor Author

As a comeback to this:
I'm sorry. My wording was too harsh

With that said, is there something that could be done here?
Because this would allow macros to solve some significant pain points in the Flutter ecosystem: flutter/flutter#51752

Issue which is closely related to other discussions on this repo, such as:

The flutter/flutter#51752 issue seem to certainly be a target use-case for static meta-programming.
But #18 and #23 shows that static meta-programming would have difficulties with solving the issue
I believe that source-maps, with the added freedom, would allow truly fixing the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants