dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.11k stars 1.57k forks source link

A macro application generated by another macro is not invoked #56042

Open alexeyinkin opened 3 months ago

alexeyinkin commented 3 months ago

In this example, MacroA generates a class CreatedByMacroA with MacroB applied to it. In turn, MacroB should generate a class CreatedByMacroB, but it does not.

main.dart:

import 'macro_a.dart';
import 'macro_b.dart';

@MacroA()
class Foo {}

void main() {
  print(CreatedByMacroB); // Error: Undefined name 'CreatedByMacroB'.
}

macro_a.dart:

import 'package:macros/macros.dart';

macro class MacroA implements ClassTypesMacro {
  const MacroA();

  @override
  Future<void> buildTypesForClass(ClassDeclaration clazz, ClassTypeBuilder builder) async {
    final macroB = await builder.resolveIdentifier(Uri.parse('package:temp1/macro_b.dart'), 'MacroB');
    builder.declareType(
      'CreatedByMacroA',
      DeclarationCode.fromParts(['@', macroB, '() class CreatedByMacroA {}']),
    );
  }
}

macro_b.dart:

import 'package:macros/macros.dart';

macro class MacroB implements ClassTypesMacro {
  const MacroB();

  @override
  Future<void> buildTypesForClass(ClassDeclaration clazz, ClassTypeBuilder builder) async {
    builder.declareType('CreatedByMacroB', DeclarationCode.fromString('class CreatedByMacroB {}'));
  }
}

The expected result is that class CreatedByMacroB exists in the scope of main.dart. According to the spec:

When creating DeclarationCode instances, a macro may generate code which includes macro applications. These macro applications must be from either the current phase or a later phase

To verify that MacroB itself in this example works, replace the application of @MacroA with @MacroB.

dart info

``` #### General info - Dart 3.5.0-180.3.beta (beta) (Wed Jun 5 15:06:15 2024 +0000) on "macos_arm64" - on macos / Version 13.6 (Build 22G120) - locale is en-GE #### Project info - sdk constraint: '^3.5.0-180' - dependencies: macros - dev_dependencies: #### Process info | Memory | CPU | Elapsed time | Command line | | -----: | ---: | -----------: | ------------------------------------------------------------------------------------------ | | 29 MB | 0.0% | 57:34 | dart devtools --no-launch-browser | | 59 MB | 0.0% | 16:31:39 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 63 MB | 0.0% | 22:48:46 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 57 MB | 0.0% | 01-21:10:07 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 64 MB | 0.0% | 15:30:28 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 60 MB | 0.0% | 15:15:53 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 67 MB | 0.0% | 01-18:36:01 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 62 MB | 0.0% | 15:05:35 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 60 MB | 0.0% | 15:04:58 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 61 MB | 0.0% | 10:39:03 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 60 MB | 0.0% | 18:14:49 | dart language-server --client-id=Android-Studio --client-version=AI-223.8836.35 --protocol=analyzer | | 43 MB | 0.0% | 04-22:33:30 | dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.90.0 | | 21 MB | 0.0% | 04-22:33:30 | dart tooling-daemon --machine | | 77 MB | 1.0% | 57:59 | flutter_tools.snapshot --no-color run --machine --track-widget-creation --device-id=chrome --start-paused --enable-experiment=macros --dart-define=flutter.inspector.structuredErrors=true lib/main.dart | | 45 MB | 0.1% | 16:31:39 | flutter_tools.snapshot daemon | | 46 MB | 0.1% | 22:48:45 | flutter_tools.snapshot daemon | | 47 MB | 0.0% | 15:30:28 | flutter_tools.snapshot daemon | | 46 MB | 0.0% | 15:15:53 | flutter_tools.snapshot daemon | | 45 MB | 0.0% | 01-18:36:01 | flutter_tools.snapshot daemon | | 43 MB | 0.0% | 18:14:49 | flutter_tools.snapshot daemon | ```

dart-github-bot commented 3 months ago

Labels: area-language, type-bug Summary: A macro application generated by another macro is not invoked. MacroA generates a class with MacroB applied to it, but MacroB's generated class is not present in the final code.