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

GeneratorForAnnotation throws if there is an unresolved annotation in the file #682

Closed
rrousselGit opened this issue Sep 27, 2023 · 14 comments · Fixed by #683
Closed

GeneratorForAnnotation throws if there is an unresolved annotation in the file #682

rrousselGit opened this issue Sep 27, 2023 · 14 comments · Fixed by #683

Comments

@rrousselGit
Copy link
Contributor

Hello!

It appears that GeneratorForAnnotation uses library.annotatedWith(typeChecker). But it does not specify throwOnUnresolved: false.
So if the file contains an unresolved annotation, that causes an error to be thrown and shown to users in the terminal.

@jakemac53
Copy link
Contributor

I am not sure exactly why we chose to throw by default here, but it was an explicit choice, so I don't know that we should swap it without understanding why it was set that way originally. For the majority of use cases I wouldn't expect to see unresolved annotations. Are these code generated later on? Can we just change the builder ordering to resolve it?

We definitely should at least provide an option to pass a custom value for throwOnUnresolved though either way.

@rrousselGit
Copy link
Contributor Author

Users of my packages saw it happen a few times while editing files.

I think the unexpected behavior is the error message. It likely feels like the generator failed.
Whereas it's likely that the user is missing an import.

@jakemac53
Copy link
Contributor

Whereas it's likely that the user is missing an import.

They should have an error in their IDE in that case?

@jakemac53
Copy link
Contributor

My main concern with making this the default is just that we could be skipping over annotations that should have been targeted silently. So that will lead to a different kind of confusion. Presumably that is why the default is to throw?

@rrousselGit
Copy link
Contributor Author

I think my users complained about a race condition.

I know that there are cases where previously generated code is picked up by the analyzer even though it should be deleted.
If there's an annotation in there, it could possibly cause this error

@jakemac53
Copy link
Contributor

jakemac53 commented Sep 27, 2023

I know that there are cases where previously generated code is picked up by the analyzer even though it should be deleted.

This shouldn't be the case. It is possible to be able to resolve certain identifiers that you shouldn't be able to though. This could lead to something being an error in one build and not the next in theory, where the error was essentially missed in one of the builds? This particular error could throw somewhat unreliably in this case.

@rrousselGit
Copy link
Contributor Author

I think that's the case yes. My users mentioned that the error goes away when restarting generation

@jakemac53
Copy link
Contributor

cc @kevmoo @natebosch wdyt about changing the default here?

@kevmoo
Copy link
Member

kevmoo commented Sep 28, 2023

🤷

@rrousselGit
Copy link
Contributor Author

rrousselGit commented Sep 28, 2023

I actually have a reliable way of reproducing this error. It seems to be introduced by a recent change in my generated code, which now generates an @annotation for custom linting purposes.

TL'DR, when a user defines:

@riverpod
Object? example(ExampleRef ref, int arg) => 0;

This generates (amongs many things):

@ProviderFor(example) // Pass the user-defined symbol to help the linter find the user code
const exampleProvider = ExampleFamily();

The problem:
Whenever the user renames example to something else, that annotation ends-up being unresolved (since the symbol example no-longer exists).

This forces folks to delete the .dart_tool folder and restart, at which point things work again.

@jakemac53
Copy link
Contributor

Whenever the user renames example to something else, that annotation ends-up being unresolved (since the symbol example no-longer exists).

Just so I understand correctly - is what you are seeing that declarations from the previously generated part file (which shouldn't exist yet in this new build) - are still present? So then it fails on those unresolved annotations, which shouldn't actually be there at all?

@rrousselGit
Copy link
Contributor Author

Correct. The error is about to go away as soon as generation completes. And the error happens before generation, while also preventing builders from fixing the issue.

So the only way out is to restart from a blank state

@rrousselGit
Copy link
Contributor Author

For what it's worth, I've already forked GeneratorForAnnotation a while ago anyway.
So this isn't critical to me and I am able to fix this on my own. If you feel like that's not important, I don't mind closing this as I wouldn't have the issue anymore.

@jakemac53
Copy link
Contributor

This looks like a legitimate bug, so I do appreciate the time you have spent diagnosing and giving a repro case and I do have a fix pending 👍

jakemac53 added a commit to dart-lang/build that referenced this issue Sep 28, 2023
Related to dart-lang/source_gen#682.

Deleted files were never getting a changeFile call and so they were still available in the analyzer. This exposed in particular old generated part files to subsequent builds which could cause weird errors.
jakemac53 added a commit that referenced this issue Sep 28, 2023
Closes #682

This only enables configuration right now, mostly to avoid any change in default behavior. I am open to changing the default too though.
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

Successfully merging a pull request may close this issue.

3 participants