dart-lang / build

A build system for Dart written in Dart
https://pub.dev/packages/build
BSD 3-Clause "New" or "Revised" License
782 stars 205 forks source link

Build runner crashes when builder implementation uses macro-generated code #3743

Open pattobrien opened 3 weeks ago

pattobrien commented 3 weeks ago

Description

When creating a Generator or Builder implementation, depending on macro-generated code crashes the builder (e.g. if the builder uses a data model class annotated with package:json @JsonCodable()).

Console output:

❯ dart --enable-experiment=macros run build_runner watch -d --enable-experiment=macros
Building package executable... 
Built build_runner:build_runner.
[INFO] Generating build script completed, took 536ms
[WARNING] ../lib/builders_interop/generator_using_macro.dart:23:2: Error: This macro application didn't apply correctly.
@JsonCodable()
 ^
../lib/builders_interop/generator_using_macro.dart:25:16: Error: Final field 'value' is not initialized.
Try to initialize the field in the declaration or in every constructor.
  final String value;
               ^^^^^
[INFO] Precompiling build script... completed, took 921ms
[SEVERE] Failed to precompile build script .dart_tool/build/entrypoint/build.dart.
This is likely caused by a misconfigured builder definition.

Example Builder Code

import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:json/json.dart';
import 'package:source_gen/source_gen.dart';

class HelloWorld {
  const HelloWorld();
}

class GeneratorUsingMacro extends GeneratorForAnnotation<HelloWorld> {
  @override
  String generateForAnnotatedElement(
    Element element,
    ConstantReader annotation,
    BuildStep buildStep,
  ) {
    // Comment the below line in/out to see build_runner crash.
    // SomeDataClass;
    return '/// Hello, world!';
  }
}

@JsonCodable()
class SomeDataClass {
  final String value;
}

Builder Declaration

Builder generatorUsingMacroBuilder(BuilderOptions options) {
  return SharedPartBuilder(
    [GeneratorUsingMacro()],
    'generator_using_macro',
  );
}
# build.yaml

  generator_using_macro:
    import: "package:macros_bugs/builder.dart"
    builder_factories: ["generatorUsingMacroBuilder"]
    build_extensions: { ".dart": [".g.part"] }
    auto_apply: dependents
    build_to: cache
    applies_builders:
      - "source_gen:combining_builder"

Additional Info

Dart SDK version: 3.6.0-149.0.dev (dev) (Wed Aug 14 11:51:04 2024 -0700) on "macos_x64"

jakemac53 commented 3 weeks ago

Support for macros in build_runner is not yet complete, so this is expected for now. When the feature is stabilized, we will focus more on this.