How to influence the order of cascaded generators?

71 views Asked by At

I want to use source generators more in my project. Something that I need to often do, is generate code that is then utilised by another generator.

For example.

I have written a generator that produces a dart file from a swagger json schema. That dart file is annotated with @JsonSerializable - so it should then trigger a serializer to be generated.

In this simple case it more of less works - however I think that's mostly down to the luck of the draw.

There are more complex scenarios, such as ones that utilise the MobX generator - these appear extremely flakey and often break when things are not generated in the correct order. Sometimes I need to just "touch" a specific file in a particular way to either break or fix the build runner.

Has this scenario been considered in the design of the source_gen subsystem, and how do I ensure this is working correctly?

Thanks,

1

There are 1 answers

3
Hamed On BEST ANSWER

I suppose you need to ensure that your generators are executed in the correct order because the orders in which generators run can sometimes affect the outcome.

You can use the build.yaml file to specify the order in which generators should run.

targets:
  $default:
    builders:
      your_generator1:
        generate_for:
          - lib/**/*.dart
      your_generator2:
        generate_for:
          - generated/**/*.dart  # Depend on the output of your_generator1

Here is a real-world sample:

targets:
  $default:
    builders:
      flutter_api|apiParser:
        enabled: true
        generate_for:
          - lib/basic_api/generated/*_receive.json
      flutter_api|api:
        enabled: true
        generate_for:
          - lib/basic_api/generated/*_send.json
          - lib/basic_api/generated/*_receive.json
      flutter_api|apiHelper:
        enabled: true

builders:
  apiParser:
    import: "./api_parser.dart"
    builder_factories: ["apiParser"]
    auto_apply: root_package
    build_extensions: { ".json": ["_result.dart"] }
    is_optional: False
    build_to: source
    runs_before:
      - flutter_api|api
    defaults:
      generate_for:
        include:
          - lib/basic_api/generated/*_receive.json

  api:
    import: "./api_builder.dart"
    builder_factories: ["apiBuilder"]
    auto_apply: root_package
    build_extensions: { ".json": [".dart"] }
    is_optional: False
    build_to: source
    runs_before:
      - flutter_api|apiHelper
    defaults:
      generate_for:
        include:
          - lib/basic_api/generated/**

  apiHelper:
    import: "./api_helper_builder.dart"
    builder_factories: ["apiHelperBuilder"]
    build_extensions: { ".dart": [".helper.dart"] }
    is_optional: False
    build_to: source
    required_inputs: ["api"]
    runs_before:
      - json_serializable
    defaults:
      generate_for:
        include:
          - lib/basic_api/helper/response_mapper.dart