From fec3f8d48553340e4c4d0defb0da7a2e6a59da3e Mon Sep 17 00:00:00 2001 From: David Morgan Date: Fri, 19 Jul 2024 11:00:42 +0200 Subject: [PATCH] Build macros, run them. Serve a service. --- .github/workflows/dart.yml | 386 +++++++++++++++++- pkgs/_macro_builder/lib/macro_builder.dart | 90 +++- pkgs/_macro_builder/mono_pkg.yaml | 5 + pkgs/_macro_builder/pubspec.yaml | 1 + .../test/macro_builder_test.dart | 51 +++ pkgs/_macro_client/lib/macro_client.dart | 4 +- pkgs/_macro_host/lib/macro_host.dart | 8 +- pkgs/_macro_runner/lib/macro_runner.dart | 7 +- pkgs/_macro_runner/pubspec.yaml | 2 + .../_macro_runner/test/macro_runner_test.dart | 33 ++ pkgs/_macro_server/lib/macro_server.dart | 7 +- pkgs/_macro_server/mono_pkg.yaml | 5 + pkgs/_macro_server/pubspec.yaml | 3 + .../_macro_server/test/macro_server_test.dart | 22 + pkgs/dart_model/lib/src/dart_model.dart | 6 +- pkgs/dart_model/test/model_test.dart | 15 +- 16 files changed, 608 insertions(+), 37 deletions(-) create mode 100644 pkgs/_macro_builder/test/macro_builder_test.dart create mode 100644 pkgs/_macro_runner/test/macro_runner_test.dart create mode 100644 pkgs/_macro_server/test/macro_server_test.dart diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 0ea6324f..165cf263 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -495,6 +495,111 @@ jobs: - job_003 - job_004 job_007: + name: "unit_test; linux; Dart 3.6.0-48.0.dev; PKG: pkgs/_macro_builder; `dart test --test-randomize-ordering-seed=random`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev;packages:pkgs/_macro_builder;commands:test" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev;packages:pkgs/_macro_builder + os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: "3.6.0-48.0.dev" + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_builder_pub_upgrade + name: pkgs/_macro_builder; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_builder + - name: "pkgs/_macro_builder; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_builder_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_builder + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_008: + name: "unit_test; linux; Dart 3.6.0-48.0.dev; PKG: pkgs/_macro_client; `dart test --test-randomize-ordering-seed=random`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev;packages:pkgs/_macro_client;commands:test" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev;packages:pkgs/_macro_client + os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: "3.6.0-48.0.dev" + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_client_pub_upgrade + name: pkgs/_macro_client; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_client + - name: "pkgs/_macro_client; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_client_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_client + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_009: + name: "unit_test; linux; Dart 3.6.0-48.0.dev; PKG: pkgs/_macro_server; `dart test --test-randomize-ordering-seed=random`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev;packages:pkgs/_macro_server;commands:test" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev;packages:pkgs/_macro_server + os:ubuntu-latest;pub-cache-hosted;sdk:3.6.0-48.0.dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: "3.6.0-48.0.dev" + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_server_pub_upgrade + name: pkgs/_macro_server; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_server + - name: "pkgs/_macro_server; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_server_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_server + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_010: name: "unit_test; linux; Dart 3.6.0-48.0.dev; PKG: pkgs/dart_model; `dart test --test-randomize-ordering-seed=random`" runs-on: ubuntu-latest steps: @@ -529,7 +634,7 @@ jobs: - job_002 - job_003 - job_004 - job_008: + job_011: name: "unit_test; linux; Dart 3.6.0-48.0.dev; PKG: tool/dart_model_generator; `dart test --test-randomize-ordering-seed=random`" runs-on: ubuntu-latest steps: @@ -564,7 +669,7 @@ jobs: - job_002 - job_003 - job_004 - job_009: + job_012: name: "unit_test; linux; Dart dev; PKG: pkgs/_analyzer_macros; `dart test --test-randomize-ordering-seed=random`" runs-on: ubuntu-latest steps: @@ -599,7 +704,7 @@ jobs: - job_002 - job_003 - job_004 - job_010: + job_013: name: "unit_test; linux; Dart dev; PKG: pkgs/_cfe_macros; `dart test --test-randomize-ordering-seed=random`" runs-on: ubuntu-latest steps: @@ -634,7 +739,112 @@ jobs: - job_002 - job_003 - job_004 - job_011: + job_014: + name: "unit_test; linux; Dart dev; PKG: pkgs/_macro_builder; `dart test --test-randomize-ordering-seed=random`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/_macro_builder;commands:test" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/_macro_builder + os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_builder_pub_upgrade + name: pkgs/_macro_builder; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_builder + - name: "pkgs/_macro_builder; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_builder_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_builder + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_015: + name: "unit_test; linux; Dart dev; PKG: pkgs/_macro_client; `dart test --test-randomize-ordering-seed=random`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/_macro_client;commands:test" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/_macro_client + os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_client_pub_upgrade + name: pkgs/_macro_client; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_client + - name: "pkgs/_macro_client; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_client_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_client + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_016: + name: "unit_test; linux; Dart dev; PKG: pkgs/_macro_server; `dart test --test-randomize-ordering-seed=random`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/_macro_server;commands:test" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:pkgs/_macro_server + os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_server_pub_upgrade + name: pkgs/_macro_server; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_server + - name: "pkgs/_macro_server; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_server_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_server + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_017: name: "unit_test; linux; Dart dev; PKG: pkgs/dart_model; `dart test --test-randomize-ordering-seed=random`" runs-on: ubuntu-latest steps: @@ -669,7 +879,7 @@ jobs: - job_002 - job_003 - job_004 - job_012: + job_018: name: "unit_test; linux; Dart dev; PKG: tool/dart_model_generator; `dart test --test-randomize-ordering-seed=random`" runs-on: ubuntu-latest steps: @@ -704,7 +914,7 @@ jobs: - job_002 - job_003 - job_004 - job_013: + job_019: name: "unit_test; windows; Dart 3.6.0-48.0.dev; PKG: pkgs/_analyzer_macros; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: @@ -729,7 +939,7 @@ jobs: - job_002 - job_003 - job_004 - job_014: + job_020: name: "unit_test; windows; Dart 3.6.0-48.0.dev; PKG: pkgs/_cfe_macros; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: @@ -754,7 +964,82 @@ jobs: - job_002 - job_003 - job_004 - job_015: + job_021: + name: "unit_test; windows; Dart 3.6.0-48.0.dev; PKG: pkgs/_macro_builder; `dart test --test-randomize-ordering-seed=random`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: "3.6.0-48.0.dev" + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_builder_pub_upgrade + name: pkgs/_macro_builder; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_builder + - name: "pkgs/_macro_builder; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_builder_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_builder + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_022: + name: "unit_test; windows; Dart 3.6.0-48.0.dev; PKG: pkgs/_macro_client; `dart test --test-randomize-ordering-seed=random`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: "3.6.0-48.0.dev" + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_client_pub_upgrade + name: pkgs/_macro_client; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_client + - name: "pkgs/_macro_client; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_client_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_client + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_023: + name: "unit_test; windows; Dart 3.6.0-48.0.dev; PKG: pkgs/_macro_server; `dart test --test-randomize-ordering-seed=random`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: "3.6.0-48.0.dev" + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_server_pub_upgrade + name: pkgs/_macro_server; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_server + - name: "pkgs/_macro_server; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_server_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_server + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_024: name: "unit_test; windows; Dart 3.6.0-48.0.dev; PKG: pkgs/dart_model; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: @@ -779,7 +1064,7 @@ jobs: - job_002 - job_003 - job_004 - job_016: + job_025: name: "unit_test; windows; Dart 3.6.0-48.0.dev; PKG: tool/dart_model_generator; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: @@ -804,7 +1089,7 @@ jobs: - job_002 - job_003 - job_004 - job_017: + job_026: name: "unit_test; windows; Dart dev; PKG: pkgs/_analyzer_macros; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: @@ -829,7 +1114,7 @@ jobs: - job_002 - job_003 - job_004 - job_018: + job_027: name: "unit_test; windows; Dart dev; PKG: pkgs/_cfe_macros; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: @@ -854,7 +1139,82 @@ jobs: - job_002 - job_003 - job_004 - job_019: + job_028: + name: "unit_test; windows; Dart dev; PKG: pkgs/_macro_builder; `dart test --test-randomize-ordering-seed=random`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_builder_pub_upgrade + name: pkgs/_macro_builder; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_builder + - name: "pkgs/_macro_builder; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_builder_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_builder + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_029: + name: "unit_test; windows; Dart dev; PKG: pkgs/_macro_client; `dart test --test-randomize-ordering-seed=random`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_client_pub_upgrade + name: pkgs/_macro_client; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_client + - name: "pkgs/_macro_client; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_client_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_client + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_030: + name: "unit_test; windows; Dart dev; PKG: pkgs/_macro_server; `dart test --test-randomize-ordering-seed=random`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - id: pkgs__macro_server_pub_upgrade + name: pkgs/_macro_server; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: pkgs/_macro_server + - name: "pkgs/_macro_server; dart test --test-randomize-ordering-seed=random" + run: "dart test --test-randomize-ordering-seed=random" + if: "always() && steps.pkgs__macro_server_pub_upgrade.conclusion == 'success'" + working-directory: pkgs/_macro_server + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_031: name: "unit_test; windows; Dart dev; PKG: pkgs/dart_model; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: @@ -879,7 +1239,7 @@ jobs: - job_002 - job_003 - job_004 - job_020: + job_032: name: "unit_test; windows; Dart dev; PKG: tool/dart_model_generator; `dart test --test-randomize-ordering-seed=random`" runs-on: windows-latest steps: diff --git a/pkgs/_macro_builder/lib/macro_builder.dart b/pkgs/_macro_builder/lib/macro_builder.dart index 826b784b..18f62305 100644 --- a/pkgs/_macro_builder/lib/macro_builder.dart +++ b/pkgs/_macro_builder/lib/macro_builder.dart @@ -2,6 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:io'; + import 'package:dart_model/dart_model.dart'; class MacroBuilder { @@ -9,15 +11,89 @@ class MacroBuilder { /// /// Each `QualifiedName` in [macroImplementations] must point to a class that /// implements `Macro` from `package:macro`. + /// + /// The [packageConfig] must include the macros and all their deps. Future build( - Iterable macroImplementations) async { - // TODO(davidmorgan): implement. - // Generated entrypoint will instantiate all the `Macro` instances pointed - // to by `macroImplementations` then pass them to `MacroClient.run` in - // `package:_macro_client`. - return BuiltMacroBundle(); + File packageConfig, Iterable macroImplementations) async { + final script = createBootstrap(macroImplementations.toList()); + + return await MacroBuild(packageConfig, script).build(); + } + + static String createBootstrap(List macros) { + final script = StringBuffer(); + for (var i = 0; i != macros.length; ++i) { + final macro = macros[i]; + script.writeln("import '${macro.uri}' as m$i;"); + } + script.write(''' +import 'dart:convert'; + +import 'package:_macro_client/macro_client.dart'; +import 'package:macro_service/macro_service.dart'; + +void main(List arguments) { + MacroClient().run( + HostEndpoint.fromJson(json.decode(arguments[0])), + ['''); + for (var i = 0; i != macros.length; ++i) { + final macro = macros[i]; + script.write('m$i.${macro.name}()'); + if (i != macros.length - 1) script.write(', '); + } + script.writeln(']);'); + script.writeln('}'); + return script.toString(); } } /// A bundle of one or more macros that's ready to execute. -class BuiltMacroBundle {} +class BuiltMacroBundle { + // TODO(davidmorgan): other formats besides executable. + final String executablePath; + + BuiltMacroBundle(this.executablePath); +} + +/// A single build. +class MacroBuild { + final File packageConfig; + final String script; + final Directory workspace = + Directory.systemTemp.createTempSync('macro_builder'); + + MacroBuild(this.packageConfig, this.script); + + Future build() async { + final scriptFile = File.fromUri(workspace.uri.resolve('bin/main.dart')); + scriptFile.parent.createSync(recursive: true); + scriptFile.writeAsStringSync(script.toString()); + + // TODO(davidmorgan): replace relative paths to absolute. + final targetPackageConfig = + File.fromUri(workspace.uri.resolve('.dart_tool/package_config.json')); + targetPackageConfig.parent.createSync(recursive: true); + targetPackageConfig + .writeAsStringSync(_makePackageConfigAbsolute(packageConfig)); + + // See package:analyzer/src/summary2/kernel_compilation_service.dart for an + // example of compiling macros using the frontend server. + // + // For now just use the command line. + + final result = Process.runSync('dart', ['compile', 'exe', 'bin/main.dart'], + workingDirectory: workspace.path); + if (result.exitCode != 0) { + throw StateError('Compile failed: ${result.stderr}'); + } + + return BuiltMacroBundle(scriptFile.parent.uri.resolve('main.exe').path); + } + + String _makePackageConfigAbsolute(File pubspec) { + final root = pubspec.parent.parent.absolute.uri; + return pubspec + .readAsStringSync() + .replaceAll('"rootUri": "../', '"rootUri": "$root'); + } +} diff --git a/pkgs/_macro_builder/mono_pkg.yaml b/pkgs/_macro_builder/mono_pkg.yaml index 15378042..457cafcd 100644 --- a/pkgs/_macro_builder/mono_pkg.yaml +++ b/pkgs/_macro_builder/mono_pkg.yaml @@ -8,3 +8,8 @@ stages: - format: sdk: - dev +- unit_test: + - test: --test-randomize-ordering-seed=random + os: + - linux + - windows diff --git a/pkgs/_macro_builder/pubspec.yaml b/pkgs/_macro_builder/pubspec.yaml index fe8a6d2d..eb07ee96 100644 --- a/pkgs/_macro_builder/pubspec.yaml +++ b/pkgs/_macro_builder/pubspec.yaml @@ -13,3 +13,4 @@ dependencies: dev_dependencies: dart_flutter_team_lints: ^3.0.0 + test: ^1.25.0 diff --git a/pkgs/_macro_builder/test/macro_builder_test.dart b/pkgs/_macro_builder/test/macro_builder_test.dart new file mode 100644 index 00000000..50175e81 --- /dev/null +++ b/pkgs/_macro_builder/test/macro_builder_test.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; +import 'dart:isolate'; + +import 'package:_macro_builder/macro_builder.dart'; +import 'package:dart_model/dart_model.dart'; +import 'package:test/test.dart'; + +void main() { + group(MacroBuilder, () { + test('bootstrap matches golden', () async { + final script = MacroBuilder.createBootstrap([ + QualifiedName('package:_test_macros/declare_x_macro.dart#DeclareX'), + QualifiedName('package:_test_macros/declare_y_macro.dart#DeclareY'), + QualifiedName( + 'package:_more_macros/other_macro.dart#OtherMacroImplementation') + ]); + + expect(script, ''' +import 'package:_test_macros/declare_x_macro.dart' as m0; +import 'package:_test_macros/declare_y_macro.dart' as m1; +import 'package:_more_macros/other_macro.dart' as m2; +import 'dart:convert'; + +import 'package:_macro_client/macro_client.dart'; +import 'package:macro_service/macro_service.dart'; + +void main(List arguments) { + MacroClient().run( + HostEndpoint.fromJson(json.decode(arguments[0])), + [m0.DeclareX(), m1.DeclareY(), m2.OtherMacroImplementation()]); +} +'''); + }); + + test('builds macros', () async { + final builder = MacroBuilder(); + + final bundle = + await builder.build(File.fromUri(Isolate.packageConfigSync!), [ + QualifiedName( + 'package:_test_macros/declare_x_macro.dart#DeclareXImplementation') + ]); + + expect(File(bundle.executablePath).existsSync(), true); + }); + }); +} diff --git a/pkgs/_macro_client/lib/macro_client.dart b/pkgs/_macro_client/lib/macro_client.dart index 0f5b7fac..58a987ea 100644 --- a/pkgs/_macro_client/lib/macro_client.dart +++ b/pkgs/_macro_client/lib/macro_client.dart @@ -2,12 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:io'; + import 'package:macro/macro.dart'; import 'package:macro_service/macro_service.dart'; class MacroClient { /// Runs [macros] for the host at [endpoint]. void run(HostEndpoint endpoint, Iterable macros) { - // TODO(davidmorgan): implement. + Socket.connect('localhost', endpoint.port); } } diff --git a/pkgs/_macro_host/lib/macro_host.dart b/pkgs/_macro_host/lib/macro_host.dart index 3831393c..e9e7982b 100644 --- a/pkgs/_macro_host/lib/macro_host.dart +++ b/pkgs/_macro_host/lib/macro_host.dart @@ -11,14 +11,12 @@ class MacroHost { final MacroServer macroServer; final MacroBuilder macroBuilder = MacroBuilder(); final MacroRunner macroRunner = MacroRunner(); - late final HostEndpoint hostEndpoint; - MacroHost._(this.macroServer, this.hostEndpoint); + MacroHost._(this.macroServer); static Future serve({required MacroHostService service}) async { - final server = MacroServer(service: service); - final endpoint = await server.serve(); - return MacroHost._(server, endpoint); + final server = await MacroServer.serve(service: service); + return MacroHost._(server); } // TODO(davidmorgan): methods for integration with analyzer+CFE go here: diff --git a/pkgs/_macro_runner/lib/macro_runner.dart b/pkgs/_macro_runner/lib/macro_runner.dart index 90007a8e..6dcc3d01 100644 --- a/pkgs/_macro_runner/lib/macro_runner.dart +++ b/pkgs/_macro_runner/lib/macro_runner.dart @@ -2,9 +2,14 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:convert'; +import 'dart:io'; + import 'package:_macro_builder/macro_builder.dart'; import 'package:macro_service/macro_service.dart'; class MacroRunner { - void run(BuiltMacroBundle macro, HostEndpoint endpoint) {} + void run(BuiltMacroBundle macro, HostEndpoint endpoint) { + Process.run(macro.executablePath, [json.encode(endpoint)]); + } } diff --git a/pkgs/_macro_runner/pubspec.yaml b/pkgs/_macro_runner/pubspec.yaml index a83f0059..0055e2c8 100644 --- a/pkgs/_macro_runner/pubspec.yaml +++ b/pkgs/_macro_runner/pubspec.yaml @@ -14,3 +14,5 @@ dependencies: dev_dependencies: dart_flutter_team_lints: ^3.0.0 + dart_model: any + test: ^1.25.0 diff --git a/pkgs/_macro_runner/test/macro_runner_test.dart b/pkgs/_macro_runner/test/macro_runner_test.dart new file mode 100644 index 00000000..6c46fdbd --- /dev/null +++ b/pkgs/_macro_runner/test/macro_runner_test.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; +import 'dart:isolate'; + +import 'package:_macro_builder/macro_builder.dart'; +import 'package:_macro_runner/macro_runner.dart'; +import 'package:dart_model/dart_model.dart'; +import 'package:macro_service/macro_service.dart'; +import 'package:test/test.dart'; + +void main() { + group(MacroRunner, () { + test('runs macros', () async { + final builder = MacroBuilder(); + final bundle = + await builder.build(File.fromUri(Isolate.packageConfigSync!), [ + QualifiedName( + 'package:_test_macros/declare_x_macro.dart#DeclareXImplementation') + ]); + + final serverSocket = await ServerSocket.bind('localhost', 0); + + final runner = MacroRunner(); + runner.run(bundle, HostEndpoint(port: serverSocket.port)); + + expect( + serverSocket.first.timeout(const Duration(seconds: 10)), completes); + }); + }); +} diff --git a/pkgs/_macro_server/lib/macro_server.dart b/pkgs/_macro_server/lib/macro_server.dart index 79d06b20..d12e2382 100644 --- a/pkgs/_macro_server/lib/macro_server.dart +++ b/pkgs/_macro_server/lib/macro_server.dart @@ -6,11 +6,12 @@ import 'package:macro_service/macro_service.dart'; class MacroServer { final MacroHostService service; + final HostEndpoint endpoint; - MacroServer({required this.service}); + MacroServer._(this.service, this.endpoint); - Future serve() async { + static Future serve({required MacroHostService service}) async { // TODO(davidmorgan): actually serve something. - return HostEndpoint(port: 12345); + return MacroServer._(service, HostEndpoint(port: 12345)); } } diff --git a/pkgs/_macro_server/mono_pkg.yaml b/pkgs/_macro_server/mono_pkg.yaml index 15378042..457cafcd 100644 --- a/pkgs/_macro_server/mono_pkg.yaml +++ b/pkgs/_macro_server/mono_pkg.yaml @@ -8,3 +8,8 @@ stages: - format: sdk: - dev +- unit_test: + - test: --test-randomize-ordering-seed=random + os: + - linux + - windows diff --git a/pkgs/_macro_server/pubspec.yaml b/pkgs/_macro_server/pubspec.yaml index ead763ff..966afefc 100644 --- a/pkgs/_macro_server/pubspec.yaml +++ b/pkgs/_macro_server/pubspec.yaml @@ -12,4 +12,7 @@ dependencies: macro_service: any dev_dependencies: + _macro_client: any + _test_macros: any dart_flutter_team_lints: ^3.0.0 + test: ^1.25.0 diff --git a/pkgs/_macro_server/test/macro_server_test.dart b/pkgs/_macro_server/test/macro_server_test.dart new file mode 100644 index 00000000..7c5d5d5f --- /dev/null +++ b/pkgs/_macro_server/test/macro_server_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:_macro_client/macro_client.dart'; +import 'package:_macro_server/macro_server.dart'; +import 'package:_test_macros/declare_x_macro.dart'; +import 'package:macro_service/macro_service.dart'; +import 'package:test/test.dart'; + +void main() { + group(MacroServer, () { + test('serves a macro service', () async { + final service = TestMacroHostService(); + final server = await MacroServer.serve(service: service); + + MacroClient().run(server.endpoint, [DeclareXImplementation()]); + }); + }); +} + +class TestMacroHostService implements MacroHostService {} diff --git a/pkgs/dart_model/lib/src/dart_model.dart b/pkgs/dart_model/lib/src/dart_model.dart index d21294fe..923666c6 100644 --- a/pkgs/dart_model/lib/src/dart_model.dart +++ b/pkgs/dart_model/lib/src/dart_model.dart @@ -6,7 +6,7 @@ import 'dart_model.g.dart'; export 'dart_model.g.dart'; -// TODO(davidmorgan): remove example when we have an actual extension method. -extension ModelExtension on Model { - String get exampleGetter => 'exampleValue'; +extension QualifiedNameExtension on QualifiedName { + String get uri => string.substring(0, string.indexOf('#')); + String get name => string.substring(string.indexOf('#') + 1); } diff --git a/pkgs/dart_model/test/model_test.dart b/pkgs/dart_model/test/model_test.dart index 4fde1815..0b03c2d7 100644 --- a/pkgs/dart_model/test/model_test.dart +++ b/pkgs/dart_model/test/model_test.dart @@ -46,10 +46,6 @@ void main() { } }; - test('has extension methods', () { - expect(model.exampleGetter, 'exampleValue'); - }); - test('maps to JSON', () { expect(model as Map, expected); }); @@ -104,4 +100,15 @@ void main() { 'JsonData']!['members']); }); }); + + group(QualifiedName, () { + test('has uri', () { + expect(QualifiedName('package:foo/foo.dart#Foo').uri, + 'package:foo/foo.dart'); + }); + + test('has name', () { + expect(QualifiedName('package:foo/foo.dart#Foo').name, 'Foo'); + }); + }); }