Skip to content

[native_assets_builder] Refactor API to ProtocolExtensions #2089

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions pkgs/native_assets_builder/lib/native_assets_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@
// BSD-style license that can be found in the LICENSE file.

export 'package:native_assets_builder/src/build_runner/build_runner.dart'
show
ApplicationAssetValidator,
BuildInputCreator,
BuildInputValidator,
BuildValidator,
LinkInputCreator,
LinkInputValidator,
LinkValidator,
NativeAssetsBuildRunner;
show BuildInputCreator, LinkInputCreator, NativeAssetsBuildRunner;
export 'package:native_assets_builder/src/model/build_result.dart'
show BuildResult;
export 'package:native_assets_builder/src/model/kernel_assets.dart';
Expand Down
99 changes: 48 additions & 51 deletions pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,6 @@ typedef LinkInputCreator = LinkInputBuilder Function();
typedef _HookValidator =
Future<ValidationErrors> Function(HookInput input, HookOutput output);

// A callback that validates the invariants of the [BuildInput].
typedef BuildInputValidator =
Future<ValidationErrors> Function(BuildInput input);

// A callback that validates the invariants of the [LinkInput].
typedef LinkInputValidator = Future<ValidationErrors> Function(LinkInput input);

// A callback that validates the output of a `hook/link.dart` invocation is
// valid (it may valid asset-type specific information).
typedef BuildValidator =
Future<ValidationErrors> Function(BuildInput input, BuildOutput outup);

// A callback that validates the output of a `hook/link.dart` invocation is
// valid (it may valid asset-type specific information).
typedef LinkValidator =
Future<ValidationErrors> Function(LinkInput input, LinkOutput output);

// A callback that validates assets emitted across all packages are valid / can
// be used together (it may valid asset-type specific information - e.g. that
// there are no classes in shared library filenames).
typedef ApplicationAssetValidator =
Future<ValidationErrors> Function(List<EncodedAsset> assets);

/// The programmatic API to be used by Dart launchers to invoke native builds.
///
/// These methods are invoked by launchers such as dartdev (for `dart run`)
Expand Down Expand Up @@ -98,18 +75,14 @@ class NativeAssetsBuildRunner {
/// This method is invoked by launchers such as dartdev (for `dart run`) and
/// flutter_tools (for `flutter run` and `flutter build`).
///
/// The given [applicationAssetValidator] is only used if the build is
/// performed without linking (i.e. [linkingEnabled] is `false`).
///
/// The native assets build runner does not support reentrancy for identical
/// [BuildInput] and [LinkInput]! For more info see:
/// https://github.com/dart-lang/native/issues/1319
///
/// The base protocol can be extended with [extensions]. See
/// [ProtocolExtension] for more documentation.
Future<BuildResult?> build({
required BuildInputCreator inputCreator,
required BuildInputValidator inputValidator,
required BuildValidator buildValidator,
required ApplicationAssetValidator applicationAssetValidator,
required List<String> buildAssetTypes,
required List<ProtocolExtension> extensions,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add docs about the extensions parameter - why do we need to pass it?

required bool linkingEnabled,
}) async {
final (buildPlan, packageGraph) = await _makePlan(
Expand All @@ -132,11 +105,15 @@ class NativeAssetsBuildRunner {
targetMetadata: globalMetadata,
)?.forEach((key, value) => metadata[key] = value);

final inputBuilder =
inputCreator()
..config.setupShared(buildAssetTypes: buildAssetTypes)
..config.setupBuild(linkingEnabled: linkingEnabled)
..setupBuildInput(metadata: metadata);
final inputBuilder = BuildInputBuilder();
inputBuilder.config.setupShared(
buildAssetTypes: [for (final e in extensions) ...e.buildAssetTypes],
);
for (final e in extensions) {
e.setupBuildInput(inputBuilder);
}
inputBuilder.config.setupBuild(linkingEnabled: linkingEnabled);
inputBuilder.setupBuildInput(metadata: metadata);

final (buildDirUri, outDirUri, outDirSharedUri) = await _setupDirectories(
Hook.build,
Expand All @@ -155,7 +132,7 @@ class NativeAssetsBuildRunner {
final input = BuildInput(inputBuilder.json);
final errors = [
...await validateBuildInput(input),
...await inputValidator(input),
for (final e in extensions) ...await e.validateBuildInput(input),
];
if (errors.isNotEmpty) {
return _printErrors(
Expand All @@ -167,8 +144,13 @@ class NativeAssetsBuildRunner {
final result = await _runHookForPackageCached(
Hook.build,
input,
(input, output) =>
buildValidator(input as BuildInput, output as BuildOutput),
(input, output) async => [
for (final e in extensions)
...await e.validateBuildOutput(
input as BuildInput,
output as BuildOutput,
),
],
null,
);
if (result == null) return null;
Expand All @@ -182,7 +164,10 @@ class NativeAssetsBuildRunner {
// in the link step if linking is enableD).
if (linkingEnabled) return hookResult;

final errors = await applicationAssetValidator(hookResult.encodedAssets);
final errors = [
for (final e in extensions)
...await e.validateApplicationAssets(hookResult.encodedAssets),
];
if (errors.isEmpty) return hookResult;

_printErrors('Application asset verification failed', errors);
Expand All @@ -195,13 +180,12 @@ class NativeAssetsBuildRunner {
/// The native assets build runner does not support reentrancy for identical
/// [BuildInput] and [LinkInput]! For more info see:
/// https://github.com/dart-lang/native/issues/1319
///
/// The base protocol can be extended with [extensions]. See
/// [ProtocolExtension] for more documentation.
Future<LinkResult?> link({
required LinkInputCreator inputCreator,
required LinkInputValidator inputValidator,
required LinkValidator linkValidator,
required ApplicationAssetValidator applicationAssetValidator,
required List<ProtocolExtension> extensions,
Uri? resourceIdentifiers,
required List<String> buildAssetTypes,
required BuildResult buildResult,
}) async {
final (buildPlan, packageGraph) = await _makePlan(
Expand All @@ -212,8 +196,13 @@ class NativeAssetsBuildRunner {

var hookResult = HookResult(encodedAssets: buildResult.encodedAssets);
for (final package in buildPlan) {
final inputBuilder =
inputCreator()..config.setupShared(buildAssetTypes: buildAssetTypes);
final inputBuilder = LinkInputBuilder();
inputBuilder.config.setupShared(
buildAssetTypes: [for (final e in extensions) ...e.buildAssetTypes],
);
for (final e in extensions) {
e.setupLinkInput(inputBuilder);
}

final (buildDirUri, outDirUri, outDirSharedUri) = await _setupDirectories(
Hook.link,
Expand Down Expand Up @@ -243,7 +232,7 @@ class NativeAssetsBuildRunner {
final input = LinkInput(inputBuilder.json);
final errors = [
...await validateLinkInput(input),
...await inputValidator(input),
for (final e in extensions) ...await e.validateLinkInput(input),
];
if (errors.isNotEmpty) {
print(input.assets.encodedAssets);
Expand All @@ -256,16 +245,24 @@ class NativeAssetsBuildRunner {
final result = await _runHookForPackageCached(
Hook.link,
input,
(input, output) =>
linkValidator(input as LinkInput, output as LinkOutput),
(input, output) async => [
for (final e in extensions)
...await e.validateLinkOutput(
input as LinkInput,
output as LinkOutput,
),
],
resourceIdentifiers,
);
if (result == null) return null;
final (hookOutput, hookDeps) = result;
hookResult = hookResult.copyAdd(hookOutput, hookDeps);
}

final errors = await applicationAssetValidator(hookResult.encodedAssets);
final errors = [
for (final e in extensions)
...await e.validateApplicationAssets(hookResult.encodedAssets),
];
if (errors.isEmpty) return hookResult;

_printErrors('Application asset verification failed', errors);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ void main() async {
dartExecutable,
capturedLogs: logMessages,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
expect(
logMessages.join('\n'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ void main() async {
createCapturingLogger(logMessages, level: Level.SEVERE),
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
);
final fullLog = logMessages.join('\n');
expect(result, isNull);
Expand Down Expand Up @@ -56,9 +53,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
);
expect(result, isNotNull);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ void main() async {
createCapturingLogger(logMessages, level: Level.SEVERE),
dartExecutable,
buildAssetTypes: [],
inputValidator: (input) async => [],
buildValidator: (input, output) async => [],
applicationAssetValidator: validateCodeAssetInApplication,
);
final fullLog = logMessages.join('\n');
expect(result, isNull);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ void main() async {
dartExecutable,
capturedLogs: logMessages,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
expect(
logMessages.join('\n'),
Expand All @@ -56,9 +53,6 @@ void main() async {
dartExecutable,
capturedLogs: logMessages,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
final hookUri = packageUri.resolve('hook/build.dart');
expect(
Expand Down Expand Up @@ -104,9 +98,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
await expectSymbols(
asset: CodeAsset.fromEncoded(result.encodedAssets.single),
Expand All @@ -127,9 +118,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;

final cUri = packageUri.resolve('src/').resolve('native_add.c');
Expand Down Expand Up @@ -166,9 +154,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
{
final compiledHook =
Expand Down Expand Up @@ -199,9 +184,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;

final hookUri = packageUri.resolve('hook/build.dart');
Expand Down Expand Up @@ -237,9 +219,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
hookEnvironment:
modifiedEnvKey == 'PATH'
? null
Expand Down Expand Up @@ -272,9 +251,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
expect(logMessages.join('\n'), contains('hook.dill'));
expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ void main() async {
createCapturingLogger(logMessages, level: Level.SEVERE),
dartExecutable,
buildAssetTypes: [],
inputValidator: (input) async => [],
buildValidator: (input, output) async => [],
applicationAssetValidator: (_) async => [],
);
final fullLog = logMessages.join('\n');
expect(result, isNull);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
expect(result.encodedAssets.length, 1);
await expectSymbols(
Expand All @@ -54,9 +51,6 @@ void main() async {
createCapturingLogger(logMessages, level: Level.SEVERE),
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
);
final fullLog = logMessages.join('\n');
expect(result, isNull);
Expand Down Expand Up @@ -87,9 +81,6 @@ void main() async {
logger,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
expect(result.encodedAssets.length, 1);
await expectSymbols(
Expand Down Expand Up @@ -121,9 +112,6 @@ void main() async {
capturedLogs: logMessages,
dartExecutable,
buildAssetTypes: [CodeAsset.type],
inputValidator: validateCodeAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
);
Matcher stringContainsBuildHookCompilation(String packageName) =>
stringContainsInOrder([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ void main() async {
capturedLogs: logMessages,
runPackageName: 'some_dev_dep',
buildAssetTypes: [CodeAsset.type],
inputValidator: validateDataAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
expect(result.encodedAssets, isEmpty);
expect(result.dependencies, isEmpty);
Expand All @@ -47,9 +44,6 @@ void main() async {
capturedLogs: logMessages,
runPackageName: 'native_add',
buildAssetTypes: [CodeAsset.type],
inputValidator: validateDataAssetBuildInput,
buildValidator: validateCodeAssetBuildOutput,
applicationAssetValidator: validateCodeAssetInApplication,
))!;
expect(result.encodedAssets, isNotEmpty);
expect(
Expand Down
Loading