dart-lang / macros

A Dart mono-repo for macro development.
BSD 3-Clause "New" or "Revised" License
90 stars 5 forks source link

`.typesOf` breaks inside a `buildDeclarationsForClass` #112

Open mateusfccp opened 1 month ago

mateusfccp commented 1 month ago

Consider this minimal macro:

import 'package:macros/macros.dart';

macro class TypesOfTest implements ClassDeclarationsMacro {
  const TypesOfTest();

  @override
  Future<void> buildDeclarationsForClass(ClassDeclaration clazz, MemberDeclarationBuilder declarationBuilder) async {
    await declarationBuilder.typesOf(clazz.library);
  }
}

Trying to apply this macro to a class returns an error:

@TypesOfTest()
final class Foo {}

Error:

Null check operator used on a null value #0      PropertyInducingElementImpl.type (package:analyzer/src/dart/element/element.dart:9430:26)
#1      PropertyAccessorElementImpl_ImplicitGetter.returnType (package:analyzer/src/dart/element/element.dart:9213:40)
#2      DeclarationBuilderFromElement._functionElement (package:analyzer/src/summary2/macro_declarations.dart:1043:37)
#3      DeclarationBuilderFromElement.functionElement (package:analyzer/src/summary2/macro_declarations.dart:724:38)
#4      DeclarationBuilderFromElement.declarationOf (package:analyzer/src/summary2/macro_declarations.dart:685:18)
#5      DeclarationBuilder.declarationOfElement (package:analyzer/src/summary2/macro_declarations.dart:179:26)
#6      _DeclarationPhaseIntrospector.typesOf.<anonymous closure> (package:analyzer/src/summary2/macro_application.dart:1288:40)
#7      MappedIterator.moveNext (dart:_internal/iterable.dart:413:20)
#8      WhereTypeIterator.moveNext (dart:_internal/iterable.dart:892:20)
#9      new _GrowableList._ofOther (dart:core-patch/growable_array.dart:202:26)
#10     new _GrowableList.of (dart:core-patch/growable_array.dart:152:26)
#11     new List.of (dart:core-patch/array_patch.dart:39:18)
#12     Iterable.toList (dart:core/iterable.dart:498:7)
#13     _DeclarationPhaseIntrospector.typesOf (package:analyzer/src/summary2/macro_application.dart:1290:10)
#14     new ExternalMacroExecutorBase.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:_macros/src/executor/executor_base.dart:194:26)
#15     _rootRun (dart:async/zone.dart:1414:13)
#16     _CustomZone.run (dart:async/zone.dart:1317:19)
#17     withRemoteInstanceZone (package:_macros/src/executor/remote_instance.dart:172:15)
#18     new ExternalMacroExecutorBase.<anonymous closure>.<anonymous closure> (package:_macros/src/executor/executor_base.dart:45:9)
#19     _rootRunUnary (dart:async/zone.dart:1430:13)
#20     _CustomZone.runUnary (dart:async/zone.dart:1324:19)
#21     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1233:7)
#22     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:366:11)
#23     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:297:7)
#24     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:777:19)
#25     _StreamController._add (dart:async/stream_controller.dart:651:7)
#26     _StreamController.add (dart:async/stream_controller.dart:606:5)
#27     _SingleIsolatedMacroExecutor.start.<anonymous closure> (package:_macros/src/executor/isolated_executor.dart:64:33)
#28     _rootRunUnary (dart:async/zone.dart:1430:13)
#29     _CustomZone.runUnary (dart:async/zone.dart:1324:19)
#30     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1233:7)
#31     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:366:11)
#32     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:297:7)
#33     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:777:19)
#34     _StreamController._add (dart:async/stream_controller.dart:651:7)
#35     _StreamController.add (dart:async/stream_controller.dart:606:5)
#36     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

I got this both in 0.1.3-main.0 and 0.1.2-main.4. I didn't test in other versions.

Using this same code but in a buildDefinitionsForClass will work.

davidmorgan commented 1 month ago

Thanks Mateus.

We are currently working on a new implementation that will replace the code in macro_application.dart, so it would make sense to revisit this after we switch to the new version.

mateusfccp commented 1 month ago

Is there any issue/PR tracking this new implementation? So I know when to revisit this issue.

davidmorgan commented 1 month ago

The API changes, see for example

https://github.com/dart-lang/macros/blob/4d3f2864aae1a136b7fd38cae03bc7de0778525d/pkgs/_test_macros/lib/json_codable.dart

so it will be a breaking change and easy to spot :)