-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Analyzer crashing while processing macro usage #55756
Comments
Code import 'package:macro_test/macro_test.dart';
@ControllerMacro()
class MyControllerText {
@CustomAnnotation()
void main() {}
}
class CustomAnnotation {
const CustomAnnotation();
} The reason it crashes is that the macro attempts to access the identifier The reason we cannot resolve annotations until after the declarations phase is that resolution potentially depends on constructors that might be added at any point during the declarations phase. From the macro API implementation inside the analyzer we don't have any better solution than to throw - @jakemac53 For any API suggestions. |
With https://dart-review.googlesource.com/c/sdk/+/366966 we will tell the name of the unresolved identifier. Theoretically we know much more - the exact AST node (so the offset), and the content of the file. So, if this happens regularly, we can provide more details to simplify identification of the problematic identifier. |
Bug: #55756 Change-Id: Ia1eab2bdf8900843151386f7dc31423e5f62805a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/366966 Reviewed-by: Phil Quitslund <pquitslund@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
The type is definitely already known, and it seems like we should be able to then know the assumed "identifier" for any constructor (it must be a const constructor with that name on that known type). So, while you can't tie the constructor identifier to a specific AST node or element, we should know everything we need to know to output a reference to that identifier as Code, which is the important part (the import URI for it plus the scope (class name) and the name of the constructor)? |
True, we should be able to resolve the type element. |
BTW, here is the script that I use to see if the example runs well, and generated code. import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
void main() async {
var collection = AnalysisContextCollectionImpl(
includedPaths: [
'/Users/scheglov/tmp/2024-05-17/AnalyzerCrashResolveIdentifier/lib/controller.dart',
],
);
var timer = Stopwatch()..start();
for (var analysisContext in collection.contexts) {
print(analysisContext.contextRoot.root.path);
var analysisSession = analysisContext.currentSession;
for (var path in analysisContext.contextRoot.analyzedFiles()) {
if (path.endsWith('.dart')) {
var libResult = await analysisSession.getResolvedLibrary(path);
if (libResult is ResolvedLibraryResult) {
for (var unitResult in libResult.units) {
print(' ${unitResult.path}');
var ep = '\n ';
print(' errors:$ep${unitResult.errors.join(ep)}');
print('---');
print(unitResult.content);
print('---');
}
}
}
}
}
print('[time: ${timer.elapsedMilliseconds} ms]');
await collection.dispose();
} |
https://dart-review.googlesource.com/c/sdk/+/366895 fixes the crash. |
…ifier. Bug: #55756 Change-Id: Ibde1628dde8d08f95c46ee7c21332a6cf4ce6bca Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/366895 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
The solution now indeed works for the const constructor annotations, though using a reference to a global const field still results in a crash. import 'package:macro_test/macro_test.dart';
@ControllerMacro()
class MyControllerText {
@CustomAnnotation()
@refAnnotation
void main() {
}
}
class CustomAnnotation {
const CustomAnnotation();
}
const refAnnotation = CustomAnnotation(); This code now fails with
As expected since 2fa0501 now outputs the reference to the offending identifier. Could there be a possibility to also assume the identifier code of the const field similarly to how constructor identifiers are assumed or is this not possible with the information known in the declaration phase? Reading @jakemac53's explanation on how this is possible for constructors also let's me assume this is possible for const fields, since we should know both the import uri of the const field's library as well as the name of the global field. |
During the declarations phase we cannot resolve identifiers that are not guaranteed to be names of types. My reading of @jakemac53 comment "you can't tie the constructor identifier to a specific AST node or element" - we don't know the element, but this does not matter because we can output the constructor name, and regardless what it is, it will be the same as the referenced by the annotation. |
Ah okay I see the problem. So if I want to have declarative macros which are copying metadata, this will only work for const constructor invocations. Thanks for clarifying! |
While playing around with macro experiment, I found following analyzer crash:
Full Log
Full Reference Code
This analyzer only crashes once I uncomment
builder.declareInType(metaCode)
incontent.dart
.The text was updated successfully, but these errors were encountered: