From 40787d84fc4ed64caad73570f8726968a161d9c6 Mon Sep 17 00:00:00 2001 From: Daco Harkes Date: Tue, 21 Feb 2023 07:29:29 +0000 Subject: [PATCH] [frontend_server] Add support for `@Native` assets The VM can read native asset mappings from kernel. Previous CLs already added support to embed native asset mappings for one-shot compilation. This CL adds support for adding native assets mappings to kernel files created by the frontend_server with the incremental compiler. The frontend_server accepts a `--native-assets=` at startup and accepts a `native-assets ` message on stdin as compilation command. The frontend_server caches the compiled native assets library. When a `reset` command is sent to request a full dill from the incremental compiler, the native assets mapping is taken from the cache and added to the final dill file. Split of DartSDK & flutter_tools prototype to land separately. TEST=pkg/frontend_server/test/native_assets_test.dart Bug: https://github.com/dart-lang/sdk/issues/49803 Bug: https://github.com/dart-lang/sdk/issues/50565 Change-Id: I6e15f177564b8a962e81261815e951e7c9525513 Cq-Include-Trybots: luci.dart.try:pkg-linux-debug-try,pkg-linux-release-try,pkg-mac-release-arm64-try,pkg-mac-release-try,pkg-win-release-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/282101 Reviewed-by: Jens Johansen Commit-Queue: Daco Harkes --- pkg/frontend_server/lib/frontend_server.dart | 119 ++++++- .../test/frontend_server_test.dart | 6 + .../test/native_assets_test.dart | 325 ++++++++++++++++++ pkg/vm/bin/kernel_service.dart | 2 +- pkg/vm/lib/kernel_front_end.dart | 34 +- pkg/vm/lib/native_assets/synthesizer.dart | 5 +- .../test/native_assets/synthesizer_test.dart | 2 +- 7 files changed, 459 insertions(+), 34 deletions(-) create mode 100644 pkg/frontend_server/test/native_assets_test.dart diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart index 605515fd0c4..b6a28ee92ea 100644 --- a/pkg/frontend_server/lib/frontend_server.dart +++ b/pkg/frontend_server/lib/frontend_server.dart @@ -99,6 +99,8 @@ ArgParser argParser = ArgParser(allowTrailingOptions: true) ..addMultiOption('source', help: 'List additional source files to include into compilation.', defaultsTo: const []) + ..addOption('native-assets', + help: 'Provide the native-assets mapping for @Native external functions.') ..addOption('target', help: 'Target model that determines what core libraries are available', allowed: [ @@ -278,6 +280,9 @@ abstract class CompilerInterface { IncrementalCompiler? generator, }); + /// Sets the native assets mapping to be embedded in the kernel. + Future setNativeAssets(String nativeAssets); + /// Assuming some Dart program was previously compiled, recompile it again /// taking into account some changed(invalidated) sources. Future recompileDelta({String? entryPoint}); @@ -400,7 +405,15 @@ class FrontendCompiler implements CompilerInterface { late bool _printIncrementalDependencies; late ProcessedOptions _processedOptions; - /// Initialized in [writeJavaScriptBundle] + /// Initialized in [compile] from options, or (re)set in [setNativeAssets]. + Uri? _nativeAssets; + + /// Cached compilation of [_nativeAssets]. + /// + /// Managed by [_compileNativeAssets] and [setNativeAssets]. + Library? _nativeAssetsLibrary; + + /// Initialized in [writeJavaScriptBundle]. IncrementalJavaScriptBundler? _bundler; /// Nullable fields @@ -443,6 +456,8 @@ class FrontendCompiler implements CompilerInterface { _mainSource = resolveInputUri(entryPoint); _additionalSources = (options['source'] as List).map(resolveInputUri).toList(); + final nativeAssets = options['native-assets'] as String?; + _nativeAssets = nativeAssets != null ? resolveInputUri(nativeAssets) : null; _kernelBinaryFilenameFull = _options['output-dill'] ?? '$entryPoint.dill'; _kernelBinaryFilenameIncremental = _options['output-incremental-dill'] ?? (_options['output-dill'] != null @@ -579,12 +594,16 @@ class FrontendCompiler implements CompilerInterface { IncrementalCompilerResult compilerResult = await _runWithPrintRedirection(() => _generator.compile()); Component component = compilerResult.component; - results = KernelCompilationResults( - component, - const {}, - compilerResult.classHierarchy, - compilerResult.coreTypes, - component.uriToSource.keys); + + await _compileNativeAssets(); + + results = KernelCompilationResults.named( + component: component, + nativeAssetsLibrary: _nativeAssetsLibrary, + classHierarchy: compilerResult.classHierarchy, + coreTypes: compilerResult.coreTypes, + compiledSources: component.uriToSource.keys, + ); incrementalSerializer = _generator.incrementalSerializer; if (options['flutter-widget-cache']) { @@ -601,6 +620,7 @@ class FrontendCompiler implements CompilerInterface { results = await _runWithPrintRedirection(() => compileToKernel( _mainSource, compilerOptions, additionalSources: _additionalSources, + nativeAssets: _nativeAssets, includePlatform: options['link-platform'], deleteToStringPackageUris: options['delete-tostring-package-uri'], aot: options['aot'], @@ -622,9 +642,13 @@ class FrontendCompiler implements CompilerInterface { options['filesystem-scheme'], options['dartdevc-module-format'], fullComponent: true); } - await writeDillFile(results, _kernelBinaryFilename, - filterExternal: importDill != null || options['minimal-kernel'], - incrementalSerializer: incrementalSerializer); + await writeDillFile( + results, + _kernelBinaryFilename, + filterExternal: importDill != null || options['minimal-kernel'], + incrementalSerializer: incrementalSerializer, + aot: options['aot'], + ); _outputStream.writeln(boundaryKey); final compiledSources = results.compiledSources!; @@ -645,6 +669,32 @@ class FrontendCompiler implements CompilerInterface { return errors.isEmpty; } + @override + Future setNativeAssets(String nativeAssets) async { + _nativeAssetsLibrary = null; // Purge compiled cache. + _nativeAssets = resolveInputUri(nativeAssets); + return true; + } + + /// Compiles [_nativeAssets] into [_nativeAssetsLibrary]. + /// + /// [compile] and [recompileDelta] invoke this, and bundles the cached + /// [_nativeAssetsLibrary] in the dill file. + Future _compileNativeAssets() async { + final nativeAssets = _nativeAssets; + if (nativeAssets == null || _nativeAssetsLibrary != null) { + return; + } + + final results = await _runWithPrintRedirection(() => compileToKernel( + null, + _compilerOptions, + nativeAssets: _nativeAssets, + environmentDefines: {}, + )); + _nativeAssetsLibrary = results.nativeAssetsLibrary; + } + Future _outputDependenciesDelta(Iterable compiledSources) async { if (!_printIncrementalDependencies) { return; @@ -744,11 +794,26 @@ class FrontendCompiler implements CompilerInterface { ]); } - writeDillFile(KernelCompilationResults results, String filename, - {bool filterExternal = false, - IncrementalSerializer? incrementalSerializer}) async { + writeDillFile( + KernelCompilationResults results, + String filename, { + bool filterExternal = false, + IncrementalSerializer? incrementalSerializer, + bool aot = false, + }) async { final Component component = results.component!; + final Library? nativeAssetsLibrary = results.nativeAssetsLibrary; + + if (aot && nativeAssetsLibrary != null) { + // If Dart component in AOT, write the vm:native-assets library _inside_ + // the Dart component. + // TODO(https://dartbug.com/50152): Support AOT dill concatenation. + component.libraries.add(nativeAssetsLibrary); + nativeAssetsLibrary.parent = component; + } + final IOSink sink = File(filename).openWrite(); + final Set loadedLibraries = results.loadedLibraries; final BinaryPrinter printer = filterExternal ? BinaryPrinter(sink, @@ -766,6 +831,14 @@ class FrontendCompiler implements CompilerInterface { } printer.writeComponentFile(component); + + if (nativeAssetsLibrary != null && !aot) { + final BinaryPrinter printer = BinaryPrinter(sink); + printer.writeComponentFile(Component( + libraries: [nativeAssetsLibrary], + mode: nativeAssetsLibrary.nonNullableByDefaultCompiledMode, + )); + } await sink.close(); if (_options['split-output-by-packages']) { @@ -856,12 +929,15 @@ class FrontendCompiler implements CompilerInterface { Component deltaProgram = deltaProgramResult.component; transformer?.transform(deltaProgram); - KernelCompilationResults results = KernelCompilationResults( - deltaProgram, - const {}, - deltaProgramResult.classHierarchy, - deltaProgramResult.coreTypes, - deltaProgram.uriToSource.keys); + await _compileNativeAssets(); + + KernelCompilationResults results = KernelCompilationResults.named( + component: deltaProgram, + classHierarchy: deltaProgramResult.classHierarchy, + coreTypes: deltaProgramResult.coreTypes, + compiledSources: deltaProgram.uriToSource.keys, + nativeAssetsLibrary: _nativeAssetsLibrary, + ); if (_compilerOptions.target!.name == 'dartdevc') { await writeJavaScriptBundle(results, _kernelBinaryFilename, @@ -1221,6 +1297,7 @@ StreamSubscription listenAndCompile(CompilerInterface compiler, case _State.READY_FOR_INSTRUCTION: const String COMPILE_INSTRUCTION_SPACE = 'compile '; const String RECOMPILE_INSTRUCTION_SPACE = 'recompile '; + const String NATIVE_ASSETS_INSTRUCTION_SPACE = 'native-assets '; const String COMPILE_EXPRESSION_INSTRUCTION_SPACE = 'compile-expression '; const String COMPILE_EXPRESSION_TO_JS_INSTRUCTION_SPACE = @@ -1242,6 +1319,10 @@ StreamSubscription listenAndCompile(CompilerInterface compiler, boundaryKey = remainder; } state = _State.RECOMPILE_LIST; + } else if (string.startsWith(NATIVE_ASSETS_INSTRUCTION_SPACE)) { + final String nativeAssets = + string.substring(NATIVE_ASSETS_INSTRUCTION_SPACE.length); + await compiler.setNativeAssets(nativeAssets); } else if (string .startsWith(COMPILE_EXPRESSION_TO_JS_INSTRUCTION_SPACE)) { // 'compile-expression-to-js diff --git a/pkg/frontend_server/test/frontend_server_test.dart b/pkg/frontend_server/test/frontend_server_test.dart index 1283a71915c..43d3d725c7d 100644 --- a/pkg/frontend_server/test/frontend_server_test.dart +++ b/pkg/frontend_server/test/frontend_server_test.dart @@ -3254,6 +3254,12 @@ class FrontendServer { .codeUnits); } + /// Sets the native assets yaml [uri]. + void setNativeAssets({required Uri uri}) { + outputParser.expectSources = true; + inputStreamController.add('native-assets $uri\n'.codeUnits); + } + /// Compiles the [expression] as if it occurs in [library]. /// /// If [className] is provided, [expression] is compiled as if it occurs in diff --git a/pkg/frontend_server/test/native_assets_test.dart b/pkg/frontend_server/test/native_assets_test.dart new file mode 100644 index 00000000000..d1134ea9ad5 --- /dev/null +++ b/pkg/frontend_server/test/native_assets_test.dart @@ -0,0 +1,325 @@ +// Copyright (c) 2023, 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.md file. + +import 'dart:async'; +import 'dart:convert'; +import 'dart:ffi'; +import 'dart:io'; + +import 'package:kernel/kernel.dart'; +import 'package:test/test.dart'; + +// Reuse some test infrastructure. +import 'frontend_server_test.dart'; + +void main() async { + group('full compiler tests', () { + final platformKernel = + computePlatformBinariesLocation().resolve('vm_platform_strong.dill'); + final sdkRoot = computePlatformBinariesLocation(); + + late Directory tempDir; + late File mainFile; + late File packageConfigFile; + late File nativeAssetsYamlFile; + late File dillFile; + + setUp(() async { + tempDir = await Directory.systemTemp.createTemp('frontendServerTest'); + + mainFile = File('${tempDir.path}/a.dart'); + await mainFile.create(recursive: true); + await mainFile.writeAsString(''' +void main() { + print(42); +} +'''); + + packageConfigFile = + File('${tempDir.path}/.dart_tool/package_config.json'); + await packageConfigFile.create(recursive: true); + await packageConfigFile.writeAsString(jsonEncode({ + "configVersion": 2, + "packages": [], + })); + + nativeAssetsYamlFile = + File('${tempDir.path}/.dart_tool/native_assets.yaml'); + await nativeAssetsYamlFile.create(recursive: true); + await nativeAssetsYamlFile.writeAsString(jsonEncode({ + 'format-version': [1, 0, 0], + 'native-assets': { + Abi.current().toString(): { + mainFile.uri.toString(): ['executable'], + }, + }, + })); + + // Other setup. + dillFile = File('${tempDir.path}/app.dill'); + }); + + tearDown(() async { + return await tempDir.delete(recursive: true); + }); + + group('--incremental', () { + testPassInNativeAssetsAtStartup({ + List additionalStartupArguments = const [], + }) async { + final frontendServer = FrontendServer(); + Future result = frontendServer.open([ + '--sdk-root=${sdkRoot.toFilePath()}', + '--incremental', + '--platform=${platformKernel.path}', + '--output-dill=${dillFile.path}', + '--native-assets=${nativeAssetsYamlFile.path}', + ]); + + frontendServer.compile(mainFile.path); + + int count = 0; + frontendServer.listen((Result compiledResult) async { + CompilationResult result = + CompilationResult.parse(compiledResult.status); + switch (count) { + case 0: + expect(await dillFile.exists(), equals(true)); + expect(result.filename, dillFile.path); + expect(result.errorsCount, 0); + count += 1; + frontendServer.accept(); + frontendServer.reset(); + + final component = loadComponentFromBinary(dillFile.path); + final nativeAssetsLibrary = _findNativeAssetsLibrary(component); + expect(nativeAssetsLibrary, isNotNull); + + final firstLib = component.libraries.first; + expect(firstLib.importUri != _nativeAssetsLibraryUri, true); + expect(nativeAssetsLibrary!.isNonNullableByDefault, + firstLib.isNonNullableByDefault); + expect(nativeAssetsLibrary.nonNullable, firstLib.nonNullable); + expect(nativeAssetsLibrary.nonNullableByDefaultCompiledMode, + firstLib.nonNullableByDefaultCompiledMode); + + await mainFile.writeAsString(''' +void main() { + print(1337); +} +'''); + + frontendServer.recompile(mainFile.uri); + break; + case 1: + expect(await dillFile.exists(), equals(true)); + expect(result.filename, dillFile.path); + expect(result.errorsCount, 0); + frontendServer.accept(); + frontendServer.quit(); + + final component = loadComponentFromBinary(dillFile.path); + final nativeAssetsLibrary = _findNativeAssetsLibrary(component); + expect(nativeAssetsLibrary, isNotNull); + + break; + } + }); + expect(await result, 0); + frontendServer.close(); + } + + test('pass in native assets at startup', () async { + await testPassInNativeAssetsAtStartup(); + }); + + test('--no-sound-null-safety', () async { + await testPassInNativeAssetsAtStartup(additionalStartupArguments: [ + '--no-sound-null-safety', + ]); + }); + + test('--incremental-serialization', () async { + await testPassInNativeAssetsAtStartup(additionalStartupArguments: [ + '--incremental-serialization', + ]); + }); + + test('set native assets later', () async { + final frontendServer = FrontendServer(); + Future result = frontendServer.open([ + '--sdk-root=${sdkRoot.toFilePath()}', + '--incremental', + '--platform=${platformKernel.path}', + '--output-dill=${dillFile.path}', + ]); + + frontendServer.compile(mainFile.path); + + int count = 0; + frontendServer.listen((Result compiledResult) async { + CompilationResult result = + CompilationResult.parse(compiledResult.status); + switch (count) { + case 0: + expect(await dillFile.exists(), equals(true)); + expect(result.filename, dillFile.path); + expect(result.errorsCount, 0); + count += 1; + frontendServer.accept(); + frontendServer.reset(); + + final component = loadComponentFromBinary(dillFile.path); + final nativeAssetsLibrary = _findNativeAssetsLibrary(component); + expect(nativeAssetsLibrary, isNull); + + frontendServer.setNativeAssets(uri: nativeAssetsYamlFile.uri); + frontendServer.recompile(mainFile.uri); + break; + case 1: + expect(await dillFile.exists(), equals(true)); + expect(result.filename, dillFile.path); + expect(result.errorsCount, 0); + frontendServer.accept(); + frontendServer.quit(); + + final component = loadComponentFromBinary(dillFile.path); + final nativeAssetsLibrary = _findNativeAssetsLibrary(component); + expect(nativeAssetsLibrary, isNotNull); + + break; + } + }); + expect(await result, 0); + frontendServer.close(); + }); + + testInitializeFromDill({ + bool passNativeAssetsOnFirstStartup = false, + bool passNativeAssetsOnSecondStartup = false, + }) async { + { + final frontendServer = FrontendServer(); + Future frontendServerResult = frontendServer.open([ + '--sdk-root=${sdkRoot.toFilePath()}', + '--incremental', + '--platform=${platformKernel.path}', + '--output-dill=${dillFile.path}', + if (passNativeAssetsOnFirstStartup) + '--native-assets=${nativeAssetsYamlFile.path}', + ]); + + frontendServer.compile(mainFile.path); + + final compiledResult = + await frontendServer.receivedResults.stream.first; + CompilationResult result = + CompilationResult.parse(compiledResult.status); + expect(await dillFile.exists(), equals(true)); + expect(result.filename, dillFile.path); + expect(result.errorsCount, 0); + + frontendServer.accept(); + frontendServer.quit(); + + final component = loadComponentFromBinary(dillFile.path); + final nativeAssetsLibrary = _findNativeAssetsLibrary(component); + expect(nativeAssetsLibrary, + passNativeAssetsOnFirstStartup ? isNotNull : isNull); + + expect(await frontendServerResult, 0); + frontendServer.close(); + } + + { + final frontendServer = FrontendServer(); + Future frontendServerResult = frontendServer.open([ + '--sdk-root=${sdkRoot.toFilePath()}', + '--incremental', + '--platform=${platformKernel.path}', + '--output-dill=${dillFile.path}', + '--initialize-from-dill=${dillFile.path}', + if (passNativeAssetsOnSecondStartup) + '--native-assets=${nativeAssetsYamlFile.path}', + ]); + + frontendServer.compile(mainFile.path); + + final compiledResult = + await frontendServer.receivedResults.stream.first; + CompilationResult result = + CompilationResult.parse(compiledResult.status); + expect(await dillFile.exists(), equals(true)); + expect(result.filename, dillFile.path); + expect(result.errorsCount, 0); + + frontendServer.accept(); + frontendServer.quit(); + + final component = loadComponentFromBinary(dillFile.path); + final nativeAssetsLibrary = _findNativeAssetsLibrary(component); + expect(nativeAssetsLibrary, + passNativeAssetsOnSecondStartup ? isNotNull : isNull); + + expect(await frontendServerResult, 0); + frontendServer.close(); + } + } + + test('--initialize-from-dill embed native-assets', () async { + // This should forget the native assets, the incremental compiler + // should be seen as an optimization, _not_ as a thing that keeps + // state intentionally. + await testInitializeFromDill(passNativeAssetsOnFirstStartup: true); + }); + + test('--initialize-from-dill second start with --native-assets', + () async { + await testInitializeFromDill(passNativeAssetsOnSecondStartup: true); + }); + + test('--initialize-from-dill replace --native-assets', () async { + // This should forget the native assets from the first invocation. + await testInitializeFromDill( + passNativeAssetsOnFirstStartup: true, + passNativeAssetsOnSecondStartup: true, + ); + }); + }); + + group('--aot --tfa', () { + test('pass in native assets at startup', () async { + final frontendServer = FrontendServer(); + Future frontendServerResult = frontendServer.open([ + '--sdk-root=${sdkRoot.toFilePath()}', + '--platform=${platformKernel.path}', + '--aot', + '--tfa', + '--output-dill=${dillFile.path}', + '--native-assets=${nativeAssetsYamlFile.path}', + mainFile.path + ]); + + expect(await frontendServerResult, 0); + frontendServer.close(); + + expect(await dillFile.exists(), equals(true)); + final component = loadComponentFromBinary(dillFile.path); + final nativeAssetsLibrary = _findNativeAssetsLibrary(component); + expect(nativeAssetsLibrary, isNotNull); + }); + }); + }); +} + +final _nativeAssetsLibraryUri = Uri.parse('vm:ffi:native-assets'); + +Library? _findNativeAssetsLibrary(Component component) { + for (final library in component.libraries) { + if (library.importUri == _nativeAssetsLibraryUri) { + return library; + } + } + return null; +} diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart index 902c79acf10..137471d3847 100644 --- a/pkg/vm/bin/kernel_service.dart +++ b/pkg/vm/bin/kernel_service.dart @@ -835,7 +835,7 @@ Future _processLoadRequest(request) async { } else { await wrapper.reject(); } - } catch(e, st) { + } catch (e, st) { port.send(CompilationResult.crash(e, st).toResponse()); return; } diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart index 80937276a0b..ee5d29e5c86 100644 --- a/pkg/vm/lib/kernel_front_end.dart +++ b/pkg/vm/lib/kernel_front_end.dart @@ -318,28 +318,32 @@ Future runCompiler(ArgResults options, String usage) async { final Component? component = results.component; final Library? nativeAssetsLibrary = results.nativeAssetsLibrary; - if (errorDetector.hasCompilationErrors || (component == null)) { + if (errorDetector.hasCompilationErrors || + (component == null && nativeAssetsLibrary == null)) { return compileTimeErrorExitCode; } final IOSink sink = new File(outputFileName).openWrite(); - final BinaryPrinter printer = new BinaryPrinter(sink, - libraryFilter: (lib) => !results.loadedLibraries.contains(lib)); - if (aot && nativeAssetsLibrary != null && aot) { - // If Dart component in AOT, write the vm:native-assets library _inside_ - // the Dart component. - component.libraries.add(nativeAssetsLibrary); - nativeAssetsLibrary.parent = component; + if (component != null) { + final BinaryPrinter printer = new BinaryPrinter(sink, + libraryFilter: (lib) => !results.loadedLibraries.contains(lib)); + if (aot && nativeAssetsLibrary != null) { + // If Dart component in AOT, write the vm:native-assets library _inside_ + // the Dart component. + // TODO(https://dartbug.com/50152): Support AOT dill concatenation. + component.libraries.add(nativeAssetsLibrary); + nativeAssetsLibrary.parent = component; + } + printer.writeComponentFile(component); } - printer.writeComponentFile(component); - if (nativeAssetsLibrary != null && !aot) { + if ((nativeAssetsLibrary != null && (!aot || component == null))) { // If no Dart component, write as separate dill. // If Dart component in JIT, write as concatenated dill, to not mess with // the incremental compiler. final BinaryPrinter printer = new BinaryPrinter(sink); printer.writeComponentFile(Component( libraries: [nativeAssetsLibrary], - mode: NonNullableByDefaultCompiledMode.Strong, + mode: nativeAssetsLibrary.nonNullableByDefaultCompiledMode, )); } await sink.close(); @@ -398,8 +402,9 @@ class KernelCompilationResults { /// /// VM-specific replacement of [kernelForProgram]. /// +/// Either [source], or [nativeAssets], or both must be non-null. Future compileToKernel( - Uri source, + Uri? source, CompilerOptions options, { List additionalSources = const [], Uri? nativeAssets, @@ -429,6 +434,11 @@ Future compileToKernel( ? NonNullableByDefaultCompiledMode.Strong : NonNullableByDefaultCompiledMode.Weak, ); + if (source == null) { + return KernelCompilationResults.named( + nativeAssetsLibrary: nativeAssetsLibrary, + ); + } final target = options.target!; options.environmentDefines = diff --git a/pkg/vm/lib/native_assets/synthesizer.dart b/pkg/vm/lib/native_assets/synthesizer.dart index 87f2592d560..7f36ae5a53d 100644 --- a/pkg/vm/lib/native_assets/synthesizer.dart +++ b/pkg/vm/lib/native_assets/synthesizer.dart @@ -72,7 +72,10 @@ class NativeAssetsSynthesizer { pragmaOptions.fieldReference: nativeAssetsConstant, })) ], - )..nonNullableByDefaultCompiledMode = nonNullableByDefaultCompiledMode; + ) + ..nonNullableByDefaultCompiledMode = nonNullableByDefaultCompiledMode + ..isNonNullableByDefault = nonNullableByDefaultCompiledMode == + NonNullableByDefaultCompiledMode.Strong; } /// Loads [nativeAssetsYamlString], validates the contents, and synthesizes diff --git a/pkg/vm/test/native_assets/synthesizer_test.dart b/pkg/vm/test/native_assets/synthesizer_test.dart index 59538a6546b..f92456e2686 100644 --- a/pkg/vm/test/native_assets/synthesizer_test.dart +++ b/pkg/vm/test/native_assets/synthesizer_test.dart @@ -30,7 +30,7 @@ native-assets: ); final libraryToString = kernelLibraryToString(component.libraries.single); final expectedKernel = '''@#C9 -library; +library /*isNonNullableByDefault*/; import self as self; constants {