sdk
sdk copied to clipboard
Macros: resolveIdentifier does not resolve identifiers exported from other libraries
If library main imports a library A, and A exports a library B, and a macro is augmenting main, then it can resolve identifiers from A but not B.
This example tries to resolve identifiers from args package. args/args.dart does not declare ArgParser class but exports it from src/arg_parser.dart. A macro fails to resolve this identifier in args/args.dart, but successfully resolves it in args/src/arg_parser.dart (and it's not a proper way because libraries under src are considered private).
main.dart:
import 'package:args/args.dart';
import 'macros.dart';
@Args()
class MyArgs {}
void main() {}
macro.dart:
import 'dart:async';
import 'package:macros/macros.dart';
final _argParserPrivateLibrary = Uri.parse('package:args/src/arg_parser.dart');
final _argsLibrary = Uri.parse('package:args/args.dart');
macro class Args implements ClassDeclarationsMacro {
const Args();
@override
Future<void> buildDeclarationsForClass(ClassDeclaration clazz, MemberDeclarationBuilder builder) async {
await builder.resolveIdentifier(_argParserPrivateLibrary, 'ArgParser'); // OK
await builder.resolveIdentifier(_argsLibrary, 'ArgParserException'); // MacroImplementationExceptionImpl
}
}
Output of dart --enable-experiment=macros run lib/main.dart:
lib/main.dart:4:2: Error: MacroImplementationExceptionImpl: Unable to find top level identifier "ArgParserException" in package:args/args.dart
null
@Args()
^
pubspec.yaml
name: args_macro_example
environment:
sdk: ^3.5.0-164
dependencies:
args: ^2.5.0
meta: ^1.15.0
macros: ^0.1.0-main.5
dart info
#### General info
- Dart 3.5.0-180.2.beta (beta) (Wed May 29 13:59:09 2024 +0000) on "macos_arm64"
- on macos / Version 13.6 (Build 22G120)
- locale is en-GE
#### Project info
- sdk constraint: '^3.5.0-164'
- dependencies: args, macros, meta
- dev_dependencies:
#### Process info
| Memory | CPU | Elapsed time | Command line |
| -----: | ---: | -----------: | ------------------------------------------------------------------------------------------ |
| 9 MB | 0.0% | 17-00:11:03 | dart --enable-asserts --pause_isolates_on_start --enable-vm-service:51163 <path>/main.dart |
| 9 MB | 0.0% | 17-00:11:26 | dart --pause_isolates_on_start --enable-vm-service:51048 run test -r json <path>/main_test.dart |
| 10 MB | 0.0% | 72-17:35:11 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 77 MB | 0.0% | 02-03:32:15 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 175 MB | 0.0% | 04:48:58 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 10 MB | 0.0% | 47-22:18:37 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 10 MB | 0.0% | 237-19:22:21 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 13 MB | 0.0% | 240-18:19:54 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 479 MB | 0.0% | 32:47 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 158 MB | 0.0% | 02-22:55:29 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 13 MB | 0.0% | 18-18:31:53 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 220 MB | 0.0% | 02-20:00:27 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer |
| 18 MB | 0.0% | 05-23:20:06 | dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.88.1 |
| 12 MB | 0.0% | 05-23:20:06 | dart tooling-daemon --machine |
| 56 MB | 0.4% | 04:48:59 | flutter_tools.snapshot daemon
This is reproducible for me on:
- The recent beta
3.5.0-180.2.beta. - The recent dev
3.5.0-202with the latestmacrospackage it supports:0.1.1-main.0
Thanks! I had noticed this too, it is on a TODO list of mine somewhere to look into it :)
@scheglov @jakemac53 @johnniwinther I'm not sure where this sits in terms of specification / implementation; do we already specify that macros can refer to exported symbols instead of having to refer to the actual source location? If so--is this purely an implementation issue; and do we expect any problems? Thanks :)
Yes, AFAIK it should by exported symbols, not only declared symbols. I know where the bug is in the analyzer :-)
https://dart-review.googlesource.com/c/sdk/+/370102
Thanks @scheglov! Then I think remaining is the corresponding CFE fix.