dart-lang / source_gen

Automatic source code generation for Dart
https://pub.dev/packages/source_gen
BSD 3-Clause "New" or "Revised" License
487 stars 107 forks source link

InconsistentAnalysisException: Requested result might be inconsistent with previously returned result #721

Open duoshankui opened 2 months ago

duoshankui commented 2 months ago

[SEVERE] retrofit_generator on example/ios/.symlinks/plugins/url_launcher_ios/pigeons/messages.dart:

Could not resolve annotation for abstract class UrlLauncherApi. [SEVERE] retrofit_generator on example/ios/.symlinks/plugins/package_info_plus/example/integration_test/package_info_plus_web_test.dart:

line 1, column 481 of asset:matrix_flutter_otc/example/ios/.symlinks/plugins/package_info_plus/example/integration_test/package_info_plus_web_test.dart: Could not resolve annotation for void main(). ╷ 1 │ @GenerateMocks([http.Client]) │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ╵

jakemac53 commented 2 months ago

Can you clarify the error you are seeing is an InconsistentAnalysisException and not a missing import resulting in an unresolved annotation (the error linked looks more like the latter, but maybe that is just the eventual result of the former error).

These issues tend to be very difficult to track down and fix. There is most likely not something we can do on the build_runner side of things here, but mockito may be able to do something.

jakemac53 commented 2 months ago

Related issues:

etc... cc @srawlins for mockito and @scheglov for the analyzer, in case something might have changed recently, but I am not aware of anything.

scheglov commented 2 months ago

There were no new changes to the analysis driver as far as I know. So, this is probably something that exists for long time. And my consistent suspicion is that there are at least two async operations where one attempt to work with AnalysisSession, while another notifies the analysis driver about changed files. Or one execution flow where all this happens, but that would be much easier to notice and fix already.

jakemac53 commented 2 months ago

And my consistent suspicion is that there are at least two async operations where one attempt to work with AnalysisSession, while another notifies the analysis driver about changed files.

Yes this definitely happens but it isn't possible to change without essentially a full rewrite of this package. From this packages perspective, stale or even inconsistent results in this case are acceptable, but the exception is much harder to deal with.

scheglov commented 2 months ago

Well, if you are OK with inconsistent results, we could do something to relax the analyzer.

IIRC, you use package:analyzer/src/clients/build_resolvers/build_resolvers.dart to create AnalysisDriverForPackageBuild, right? If so, theoretically, we could add a configuration that disables the check that produces InconsistentAnalysisException.

@bwilkerson Does this sound reasonable to you?

bwilkerson commented 2 months ago

It sounds dangerous. Maybe that's because I don't know enough to understand why it isn't a problem for this package, or maybe because it's actually dangerous even in this context.

jakemac53 commented 2 months ago

It is dangerous. But, I think we have quite a lot of previous history here to tell us that it isn't a major issue. At least compared to the exceptions, which we get issues filed about on a fairly regular basis. In contrast, I am not aware of any issue reporting inconsistent builds (although that doesn't mean it never happened).

Essentially, the exception always causes a failed build, but only some (assumed small) subset of those failures would have actually resulted in an inconsistent build result (the builder would have to be relying on whatever caused the analysis to change). Most likely the change was in some deep transitive dependency and not something the code generator cared about.

jakemac53 commented 2 months ago

To get concrete about the case that can break, it is only that files which are not readable by the current build step, are actually generated and provided to the analyzer while the current build step is running, which invalidates the analysis context that it has, because the file did not originally exist.

So, you can go from having some analysis which is in a partially incomplete state, to one which is more complete.

scheglov commented 2 months ago

https://dart-review.googlesource.com/c/sdk/+/386862