Version 3.9.0-205.0.dev Merge 9d6c5d40d01a1d876c18927fcc9626f2e86b2674 into dev
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart index d13b076..c334a5c 100644 --- a/pkg/analysis_server/lib/src/context_manager.dart +++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -227,7 +227,7 @@ HashMap<Folder, AnalysisDriver>(); /// Subscriptions to watch included resources for changes. - final Set<StreamSubscription<WatchEvent>> watcherSubscriptions = {}; + final List<StreamSubscription<WatchEvent>> watcherSubscriptions = []; /// Whether or not the watchers have been paused. /// @@ -623,24 +623,12 @@ for (var included in analysisContext.contextRoot.included) { var watcher = included.watch(); watchers.add(watcher); - var watcherSubscription = watcher.changes.listen( - _scheduleWatchEvent, - onError: _handleWatchInterruption, + watcherSubscriptions.add( + watcher.changes.listen( + _scheduleWatchEvent, + onError: _handleWatchInterruption, + ), ); - watcherSubscriptions.add(watcherSubscription); - // When a directory is deleted, the watcher will be closed. Detect - // this by checking whether the watcher is still active in - // `changeSubscriptions` (it will first be removed if we are - // closing the watcher ourselves). - watcherSubscription.onDone(() { - if (watcherSubscriptions.contains(watcherSubscription)) { - _instrumentationService.logInfo( - 'Watcher for $rootFolder unexpectedly closed. ' - 'Assuming root was deleted, rebuilding...', - ); - refresh(); - } - }); } _watchBlazeFilesIfNeeded(rootFolder, driver); @@ -778,14 +766,10 @@ } Future<void> _destroyAnalysisContexts() async { - // Clear `watcherSubscriptions` before cancelling each subscription - // because the presences of a watcher in `watcherSubscriptions` is used - // to know if the watcher closed prematurely. - var subscriptionsToCancel = watcherSubscriptions.toSet(); + for (var subscription in watcherSubscriptions) { + await subscription.cancel(); + } watcherSubscriptions.clear(); - await Future.wait( - subscriptionsToCancel.map((subscription) => subscription.cancel()), - ); var collection = _collection; _collection = null;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_inline_value.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_inline_value.dart index 9f1d453..9f0fc73 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_inline_value.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_inline_value.dart
@@ -92,6 +92,7 @@ server.lspClientConfiguration, collector, function, + stoppedOffset, ); function.accept(visitor); @@ -139,7 +140,7 @@ final Range rangeAlreadyExecuted; /// A [LineInfo] used to convert offsets to lines/columns for comparing to - /// [applicableRange]. + /// locations provided by the client. final LineInfo lineInfo; _InlineValueCollector( @@ -263,12 +264,33 @@ final _InlineValueCollector collector; final AstNode rootNode; - _InlineValueVisitor(this.clientConfiguration, this.collector, this.rootNode); + /// The offset where execution currently is. + /// + /// This is used to determine which block of code we're inside, so we can + /// avoid showing inline values in other branches. + final int currentExecutionOffset; + + _InlineValueVisitor( + this.clientConfiguration, + this.collector, + this.rootNode, + this.currentExecutionOffset, + ); bool get experimentalInlineValuesProperties => clientConfiguration.global.experimentalInlineValuesProperties; @override + void visitBlock(Block node) { + if (currentExecutionOffset < node.offset || + currentExecutionOffset > node.end) { + return; + } + + super.visitBlock(node); + } + + @override void visitFormalParameter(FormalParameter node) { var name = node.name; if (name != null) { @@ -360,6 +382,16 @@ } @override + void visitSwitchPatternCase(SwitchPatternCase node) { + if (currentExecutionOffset < node.offset || + currentExecutionOffset > (node.statements.endToken?.end ?? node.end)) { + return; + } + + super.visitSwitchPatternCase(node); + } + + @override void visitVariableDeclaration(VariableDeclaration node) { var name = node.name; collector.recordVariableLookup(
diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart index f5c92ec..cf7b681 100644 --- a/pkg/analysis_server/test/integration/analysis/error_test.dart +++ b/pkg/analysis_server/test/integration/analysis/error_test.dart
@@ -18,38 +18,7 @@ @reflectiveTest class AnalysisErrorIntegrationTest extends AbstractAnalysisServerIntegrationTest { - Future<void> test_analysisRootDeleted_rebuildsContexts() async { - // To simplify testing, use two analysis roots. When we delete one of them - // we can use the notification of diagnostics sent for the other as - // validation that contexts were rebuilt. - var rootToKeepPath = sourcePath('packageKeep'); - var filetoKeepPath = sourcePath('packageKeep/lib/test.dart'); - var rootToDeletePath = sourcePath('packageDelete'); - var fileToDeletePath = sourcePath('packageDelete/lib/test.dart'); - var content = 'invalidCode'; - - // Create the folders/files up-front. - writeFile(filetoKeepPath, content); - writeFile(fileToDeletePath, content); - - await sendServerSetSubscriptions([ServerService.STATUS]); - await sendAnalysisSetAnalysisRoots([rootToKeepPath, rootToDeletePath], []); - await analysisFinished; - - // Start listening for the kept root being re-analyzed as a signal that - // the rebuild has completed. - var keptFileDiagnostics = onAnalysisErrors.firstWhere( - (params) => params.file == filetoKeepPath, - ); - - // Delete the folder which should trigger a rebuild. - deleteFolder(rootToDeletePath); - - // Ensure this completes. - await keptFileDiagnostics; - } - - Future<void> test_analysisRootDoesNotExist_addOverlay() async { + Future<void> test_analysisRootDoesNotExist() async { var packagePath = sourcePath('package'); var filePath = sourcePath('package/lib/test.dart'); var content = '''
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart index 03f75f6..4853374 100644 --- a/pkg/analysis_server/test/lsp/definition_test.dart +++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -1099,6 +1099,21 @@ await testContents(contents); } + Future<void> test_unexisting_implicit_new_constructor() async { + var contents = ''' +class [!A!] { + A.constructor(); +} + +void f() { + // ignore: new_with_undefined_constructor_default + A^(); +} +'''; + + await testContents(contents); + } + Future<void> test_unopenFile() async { var contents = ''' [!foo!]() {
diff --git a/pkg/analysis_server/test/lsp/inline_value_test.dart b/pkg/analysis_server/test/lsp/inline_value_test.dart index a960fcb..2c7e91c 100644 --- a/pkg/analysis_server/test/lsp/inline_value_test.dart +++ b/pkg/analysis_server/test/lsp/inline_value_test.dart
@@ -25,6 +25,55 @@ /// client configuration passed during initialization. bool experimentalInlineValuesProperties = false; + Future<void> test_block_ifStatement_inside() async { + code = TestCode.parse(r''' +void f(int a, int b, int c) { + if (a == 1) { + /*[0*/a/*0]*/; + /*[1*/b/*1]*/; + /*[2*/c/*2]*/; + ^ + } +} +'''); + + await verify_values(code, ofType: InlineValueVariableLookup); + } + + Future<void> test_block_ifStatement_notInside() async { + code = TestCode.parse(r''' +void f(int a, int /*[0*/b/*0]*/, int c) { + if (/*[1*/a/*1]*/ == 1) { + // Code inside blocks is excluded + a; + b; + c; + } + ^/*[2*/c/*2]*/; +} +'''); + + await verify_values(code, ofType: InlineValueVariableLookup); + } + + Future<void> test_block_switchStatement() async { + code = TestCode.parse(r''' +void f(int a, int /*[0*/b/*0]*/, int c) { + switch (/*[1*/a/*1]*/) { + case 0: + // Ignored because not in this case + a; + b; + c; + case 1: + ^/*[2*/c/*2]*/; + } +} +'''); + + await verify_values(code, ofType: InlineValueVariableLookup); + } + Future<void> test_iterables() async { experimentalInlineValuesProperties = true;
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart index 911443f..12c9c26 100644 --- a/pkg/analyzer/lib/src/error/codes.g.dart +++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -1417,7 +1417,8 @@ static const CompileTimeErrorCode DOT_SHORTHAND_UNDEFINED_INVOCATION = CompileTimeErrorCode( 'DOT_SHORTHAND_UNDEFINED_MEMBER', - "The static method or constructor '{0}' isn't defined for the type '{1}'.", + "The static method or constructor '{0}' isn't defined for the context type " + "'{1}'.", correctionMessage: "Try correcting the name to the name of an existing static method or " "constructor, or defining a static method or constructor named '{0}'.",
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index e455354..4d8b0d1 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -330,9 +330,6 @@ /// used to access the types from the core library. The [errorListener] is the /// error listener that will be informed of any errors that are found during /// resolution. - /// - // TODO(paulberry): make [featureSet] a required parameter (this will be a - // breaking change). ResolverVisitor( InheritanceManager3 inheritanceManager, LibraryElementImpl definingLibrary,
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml index a5cba99..a8df094 100644 --- a/pkg/analyzer/messages.yaml +++ b/pkg/analyzer/messages.yaml
@@ -3879,6 +3879,51 @@ experiment: dot-shorthands problemMessage: "A dot shorthand can't be used where there is no context type." hasPublishedDocs: false + documentation: |- + #### Description + + The analyzer produces this diagnostic when a dot shorthand is used where + there is no context type. + + #### Example + + The following code produces this diagnostic because there is no context + type for the expression `.a`: + + ```dart + void f() { + var e = [!.a!]; + print(e); + } + + enum E {a, b} + ``` + + #### Common fixes + + If you want to use a dot shorthand, then add a context type, which in this + example means adding the explicit type `E` to the local variable: + + ```dart + void f() { + E e = .a; + print(e); + } + + enum E {a, b} + ``` + + If you don't want to add a context type, then specify the name of the + type containing the member being referenced, which in this case is `E`: + + ```dart + void f() { + var e = E.a; + print(e); + } + + enum E {a, b} + ``` DOT_SHORTHAND_UNDEFINED_GETTER: sharedName: DOT_SHORTHAND_UNDEFINED_MEMBER experiment: dot-shorthands @@ -3889,10 +3934,55 @@ Parameters: 0: the name of the static getter 1: the name of the enclosing type where the getter is being looked for + documentation: |- + #### Description + + The analyzer produces this diagnostic when a dot shorthand is used to + reference a member, but that member doesn't exist. + + #### Example + + The following code produces this diagnostic because the enum `E` doesn't + define a static member named `c`: + + ```dart + void f() { + E e = .[!c!]; + print(e); + } + + enum E {a, b} + ``` + + #### Common fixes + + If the name is correct, then define a member with that name in the context + type, which in this case is the enum `E`: + + ```dart + void f() { + E e = .c; + print(e); + } + + enum E {a, b, c} + ``` + + If the name is not correct, then replace the name with the name of an + existing member from the context type, which in this case is the enum `E`: + + ```dart + void f() { + E e = .b; + print(e); + } + + enum E {a, b} + ``` DOT_SHORTHAND_UNDEFINED_INVOCATION: sharedName: DOT_SHORTHAND_UNDEFINED_MEMBER experiment: dot-shorthands - problemMessage: "The static method or constructor '{0}' isn't defined for the type '{1}'." + problemMessage: "The static method or constructor '{0}' isn't defined for the context type '{1}'." correctionMessage: "Try correcting the name to the name of an existing static method or constructor, or defining a static method or constructor named '{0}'." hasPublishedDocs: false comment: |-
diff --git a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation_dart.dart index 5e8859c7..b97b3a0 100644 --- a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation_dart.dart +++ b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation_dart.dart
@@ -455,6 +455,17 @@ } @override + void visitInstanceCreationExpression(InstanceCreationExpression node) { + if (node.constructorName.element == null) { + computer._addRegionForElement( + node.constructorName, + node.constructorName.type.element2, + ); + } + super.visitInstanceCreationExpression(node); + } + + @override void visitLibraryDirective(LibraryDirective node) { computer._addRegionForElement(node.name2, node.element2); super.visitLibraryDirective(node);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart index 2571b8a..d04a2e4 100644 --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -416,16 +416,24 @@ js.LiteralString partFileName, { js.Expression? code, }) { - return js.js.statement( - '((s,d,e) => {s[d] = s[d] || {}; s[d][e] = s[d][e] || [];' - 's[d][e].push({p:#part,e:"beginPart"});})' - '(self,#deferredInitializers, #eventLog)', - { - 'deferredInitializers': js.string(deferredInitializersGlobal), - 'eventLog': js.string(INITIALIZATION_EVENT_LOG), - 'part': partFileName, - }, - ); + if (_options.enableDeferredLoadingEventLog) { + return js.js.statement( + '((s,d,e) => {s[d] = s[d] || {}; s[d][e] = s[d][e] || [];' + 's[d][e].push({p:#part,e:"beginPart"});})' + '(self,#deferredInitializers, #eventLog)', + { + 'deferredInitializers': js.string(deferredInitializersGlobal), + 'eventLog': js.string(INITIALIZATION_EVENT_LOG), + 'part': partFileName, + }, + ); + } else { + return js.js.statement( + '((s,d) => {s[d] = s[d] || {};})' + '(self,#deferredInitializers)', + {'deferredInitializers': js.string(deferredInitializersGlobal)}, + ); + } } js.Statement buildStartupMetrics() { @@ -684,17 +692,28 @@ String hash = hasher.getHash(); // Now we copy the deferredInitializer.current into its correct hash. - final epilogue = js.js.statement( - '((d,h)=>{d[h]=d.current; ' - 'd.#eventLog.push({p:#part,e:"endPart",h:h})})' - '(#deferredInitializers,#hash)', - { - 'deferredInitializers': deferredInitializersGlobal, - 'hash': js.string(hash), - 'eventLog': js.string(INITIALIZATION_EVENT_LOG), - 'part': outputFileJsString, - }, - ); + js.Statement epilogue; + if (_options.enableDeferredLoadingEventLog) { + epilogue = js.js.statement( + '((d,h)=>{d[h]=d.current; ' + 'd.#eventLog.push({p:#part,e:"endPart",h:h})})' + '(#deferredInitializers,#hash)', + { + 'deferredInitializers': deferredInitializersGlobal, + 'hash': js.string(hash), + 'eventLog': js.string(INITIALIZATION_EVENT_LOG), + 'part': outputFileJsString, + }, + ); + } else { + epilogue = js.js.statement( + '((d)=>{d[#hash]=d.current;})(#deferredInitializers)', + { + 'deferredInitializers': deferredInitializersGlobal, + 'hash': js.string(hash), + }, + ); + } output.add('\n'); output.add( js
diff --git a/pkg/compiler/test/dump_info/data/deferred/main.dart b/pkg/compiler/test/dump_info/data/deferred/main.dart index 948eed2..8cb8dcf 100644 --- a/pkg/compiler/test/dump_info/data/deferred/main.dart +++ b/pkg/compiler/test/dump_info/data/deferred/main.dart
@@ -105,7 +105,7 @@ "id": "outputUnit/1", "kind": "outputUnit", "name": "1", - "size": 1184, + "size": 1035, "filename": "out_1.part.js", "imports": [ "lib"
diff --git a/pkg/compiler/test/dump_info/data/deferred_future/main.dart b/pkg/compiler/test/dump_info/data/deferred_future/main.dart index f4dfd9b..5f3d7fb 100644 --- a/pkg/compiler/test/dump_info/data/deferred_future/main.dart +++ b/pkg/compiler/test/dump_info/data/deferred_future/main.dart
@@ -113,7 +113,7 @@ "id": "outputUnit/1", "kind": "outputUnit", "name": "1", - "size": 908, + "size": 759, "filename": "out_1.part.js", "imports": [ "lib1"
diff --git a/pkg/compiler/test/end_to_end/bundle_parts_test.dart b/pkg/compiler/test/end_to_end/bundle_parts_test.dart index 822b45f..811b559 100644 --- a/pkg/compiler/test/end_to_end/bundle_parts_test.dart +++ b/pkg/compiler/test/end_to_end/bundle_parts_test.dart
@@ -15,6 +15,17 @@ if (!\$__dart_deferred_initializers__) { throw 'Did not intialize \$__dart_deferred_initializers__'; } +// Expect 'current', and 2 hashes for part files. +if (Object.keys(\$__dart_deferred_initializers__).length != 3) { + var data = JSON.stringify(\$__dart_deferred_initializers__); + throw '\$__dart_deferred_initializers__ has unexpected format: ' + data; +} +'''; + +const String verifyPartsWithEventLog = ''' +if (!\$__dart_deferred_initializers__) { + throw 'Did not intialize \$__dart_deferred_initializers__'; +} // Expect 'eventLog', 'current', and 2 hashes for part files. if (Object.keys(\$__dart_deferred_initializers__).length != 4) { var data = JSON.stringify(\$__dart_deferred_initializers__); @@ -26,7 +37,10 @@ return Directory.systemTemp.createTemp('dart2js_bundle_parts_test-'); } -Future<void> runTestWithOptions(List<String> options) async { +Future<void> runTestWithOptions( + List<String> options, + String verificationString, +) async { print('Running with flags: $options'); final tmpDir = await createTempDir(); Uri inUri = Platform.script.resolve('deferred_data/deferred_main.dart'); @@ -41,7 +55,10 @@ await part2.readAsBytes(), mode: FileMode.append, ); - await bundledParts.writeAsString('\n$verifyParts', mode: FileMode.append); + await bundledParts.writeAsString( + '\n$verificationString', + mode: FileMode.append, + ); final result = executeJsWithD8([bundledPartsUri]); if (result.exitCode != 0) { Expect.fail( @@ -53,6 +70,10 @@ } void main() async { - await runTestWithOptions([]); - await runTestWithOptions(['--minify']); + await runTestWithOptions([], verifyParts); + await runTestWithOptions(['--minify'], verifyParts); + await runTestWithOptions([ + '--minify', + '--log-deferred-loading-events', + ], verifyPartsWithEventLog); }
diff --git a/pkg/dev_compiler/lib/ddc.dart b/pkg/dev_compiler/lib/ddc.dart index e85a1d5..923fc3d 100755 --- a/pkg/dev_compiler/lib/ddc.dart +++ b/pkg/dev_compiler/lib/ddc.dart
@@ -38,8 +38,10 @@ var batch = _BatchHelper(); await batch._runBatch(parsedArgs); } else if (parsedArgs.isExpressionCompiler) { - await ExpressionCompilerWorker.createAndStart(parsedArgs.rest, - sendPort: sendPort); + await ExpressionCompilerWorker.createAndStart( + parsedArgs.rest, + sendPort: sendPort, + ); } else { var result = await compile(parsedArgs); exitCode = result.exitCode; @@ -52,7 +54,7 @@ final ParsedArguments _startupArgs; _CompilerWorker(this._startupArgs, AsyncWorkerConnection workerConnection) - : super(connection: workerConnection); + : super(connection: workerConnection); /// Keeps track of our last compilation result so it can potentially be /// re-used in a worker. @@ -72,12 +74,17 @@ } lastResult = await runZoned( - () => compile(args, - compilerState: context?.kernelState, inputDigests: inputDigests), - zoneSpecification: - ZoneSpecification(print: (self, parent, zone, message) { - output.writeln(message.toString()); - })); + () => compile( + args, + compilerState: context?.kernelState, + inputDigests: inputDigests, + ), + zoneSpecification: ZoneSpecification( + print: (self, parent, zone, message) { + output.writeln(message.toString()); + }, + ), + ); return WorkResponse() ..exitCode = lastResult!.success ? 0 : 1 ..output = output.toString(); @@ -108,10 +115,13 @@ Future _runBatch(ParsedArguments batchArgs) async { _workaroundForLeakingBug(); if (leakTesting) { - var services = - await Service.controlWebServer(enable: true, silenceOutput: true); - File.fromUri(Directory.systemTemp.uri.resolve('./dart_leak_test_uri')) - .writeAsStringSync(services.serverUri!.toString()); + var services = await Service.controlWebServer( + enable: true, + silenceOutput: true, + ); + File.fromUri( + Directory.systemTemp.uri.resolve('./dart_leak_test_uri'), + ).writeAsStringSync(services.serverUri!.toString()); } watch.start(); @@ -164,12 +174,18 @@ void _workaroundForLeakingBug() { try { stdin.echoMode; - } catch (e) {/**/} + } catch (e) { + /**/ + } try { stdout.writeln(); - } catch (e) {/**/} + } catch (e) { + /**/ + } try { stderr.writeln(); - } catch (e) {/**/} + } catch (e) { + /**/ + } } }
diff --git a/pkg/dev_compiler/lib/src/command/arguments.dart b/pkg/dev_compiler/lib/src/command/arguments.dart index e239a9b..a967850 100644 --- a/pkg/dev_compiler/lib/src/command/arguments.dart +++ b/pkg/dev_compiler/lib/src/command/arguments.dart
@@ -59,15 +59,15 @@ this.isExpressionCompiler = false, }); - /// Preprocess arguments to determine whether DDK is used in batch mode or as a - /// persistent worker. + /// Preprocess arguments to determine whether DDK is used in batch mode or as + /// a persistent worker. /// /// When used in batch mode, we expect a `--batch` parameter. /// /// When used as a persistent bazel worker, the `--persistent_worker` might be - /// present, and an argument of the form `@path/to/file` might be provided. The - /// latter needs to be replaced by reading all the contents of the - /// file and expanding them into the resulting argument list. + /// present, and an argument of the form `@path/to/file` might be provided. + /// The `@latter needs to be replaced by reading all the contents of the file + /// and expanding them into the resulting argument list. factory ParsedArguments.from(List<String> args) { if (args.isEmpty) return ParsedArguments._(args); @@ -101,12 +101,14 @@ newArgs.add(arg); } } - return ParsedArguments._(newArgs, - isWorker: isWorker, - isBatch: isBatch, - reuseResult: reuseResult, - useIncrementalCompiler: useIncrementalCompiler, - isExpressionCompiler: isExpressionCompiler); + return ParsedArguments._( + newArgs, + isWorker: isWorker, + isBatch: isBatch, + reuseResult: reuseResult, + useIncrementalCompiler: useIncrementalCompiler, + isExpressionCompiler: isExpressionCompiler, + ); } /// Whether the compiler is running in [isBatch] or [isWorker] mode. @@ -128,12 +130,14 @@ if (newArgs.isBatchOrWorker) { throw ArgumentError('cannot change batch or worker mode after startup.'); } - return ParsedArguments._(rest.toList()..addAll(newArgs.rest), - isWorker: isWorker, - isBatch: isBatch, - reuseResult: reuseResult || newArgs.reuseResult, - useIncrementalCompiler: - useIncrementalCompiler || newArgs.useIncrementalCompiler); + return ParsedArguments._( + rest.toList()..addAll(newArgs.rest), + isWorker: isWorker, + isBatch: isBatch, + reuseResult: reuseResult || newArgs.reuseResult, + useIncrementalCompiler: + useIncrementalCompiler || newArgs.useIncrementalCompiler, + ); } }
diff --git a/pkg/dev_compiler/lib/src/command/command.dart b/pkg/dev_compiler/lib/src/command/command.dart index a45e6a0..fe7f588 100644 --- a/pkg/dev_compiler/lib/src/command/command.dart +++ b/pkg/dev_compiler/lib/src/command/command.dart
@@ -9,7 +9,8 @@ import 'package:args/args.dart'; import 'package:build_integration/file_system/multi_root.dart'; import 'package:front_end/src/api_unstable/ddc.dart' as fe; -import 'package:kernel/binary/ast_from_binary.dart' as kernel +import 'package:kernel/binary/ast_from_binary.dart' + as kernel show BinaryBuilder; import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter; import 'package:kernel/class_hierarchy.dart'; @@ -46,19 +47,24 @@ /// /// The result may also contain a [previousResult], which can be passed back in /// for batch/worker executions to attempt to existing state. -Future<CompilerResult> compile(ParsedArguments args, - {fe.InitializedCompilerState? compilerState, - Map<Uri, List<int>>? inputDigests}) { +Future<CompilerResult> compile( + ParsedArguments args, { + fe.InitializedCompilerState? compilerState, + Map<Uri, List<int>>? inputDigests, +}) { if (compilerState != null && !args.isBatchOrWorker) { throw ArgumentError( - 'previousResult requires --batch or --bazel_worker mode/'); + 'previousResult requires --batch or --bazel_worker mode/', + ); } try { - return _compile(args.rest, - compilerState: compilerState, - isWorker: args.isWorker, - useIncrementalCompiler: args.useIncrementalCompiler, - inputDigests: inputDigests); + return _compile( + args.rest, + compilerState: compilerState, + isWorker: args.isWorker, + useIncrementalCompiler: args.useIncrementalCompiler, + inputDigests: inputDigests, + ); } catch (error, stackTrace) { print(''' We're sorry, you've found a bug in our compiler. @@ -83,38 +89,63 @@ 'Usage: $_binaryName [options...] <sources...>\n\n' '${ddcArgParser.usage}'; -Future<CompilerResult> _compile(List<String> args, - {fe.InitializedCompilerState? compilerState, - bool isWorker = false, - bool useIncrementalCompiler = false, - Map<Uri, List<int>>? inputDigests}) async { +Future<CompilerResult> _compile( + List<String> args, { + fe.InitializedCompilerState? compilerState, + bool isWorker = false, + bool useIncrementalCompiler = false, + Map<Uri, List<int>>? inputDigests, +}) async { // TODO(jmesserly): refactor options to share code with dartdevc CLI. var argParser = ArgParser(allowTrailingOptions: true) - ..addFlag('help', - abbr: 'h', help: 'Display this message.', negatable: false) + ..addFlag( + 'help', + abbr: 'h', + help: 'Display this message.', + negatable: false, + ) ..addOption('packages', help: 'The package spec file to use.') // TODO(jmesserly): is this still useful for us, or can we remove it now? - ..addFlag('summarize-text', - help: 'Emit API summary and AST in .js.txt and .ast.xml files.', - defaultsTo: false, - hide: true) - ..addFlag('track-widget-creation', - help: 'Enable inspecting of Flutter widgets.', - defaultsTo: false, - hide: true) + ..addFlag( + 'summarize-text', + help: 'Emit API summary and AST in .js.txt and .ast.xml files.', + defaultsTo: false, + hide: true, + ) + ..addFlag( + 'track-widget-creation', + help: 'Enable inspecting of Flutter widgets.', + defaultsTo: false, + hide: true, + ) // TODO(jmesserly): add verbose help to show hidden options - ..addOption('dart-sdk-summary', - help: 'The path to the Dart SDK summary file.', hide: true) - ..addMultiOption('multi-root', - help: 'The directories to search when encountering uris with the ' - 'specified multi-root scheme.', - defaultsTo: [Uri.base.path]) - ..addFlag('compile-sdk', - help: 'Build an SDK module.', defaultsTo: false, hide: true) - ..addOption('libraries-file', - help: 'The path to the libraries.json file for the sdk.') - ..addOption('used-inputs-file', - help: 'If set, the file to record inputs used.', hide: true); + ..addOption( + 'dart-sdk-summary', + help: 'The path to the Dart SDK summary file.', + hide: true, + ) + ..addMultiOption( + 'multi-root', + help: + 'The directories to search when encountering uris with the ' + 'specified multi-root scheme.', + defaultsTo: [Uri.base.path], + ) + ..addFlag( + 'compile-sdk', + help: 'Build an SDK module.', + defaultsTo: false, + hide: true, + ) + ..addOption( + 'libraries-file', + help: 'The path to the libraries.json file for the sdk.', + ) + ..addOption( + 'used-inputs-file', + help: 'If set, the file to record inputs used.', + hide: true, + ); Options.addArguments(argParser); var declaredVariables = parseAndRemoveDeclaredVariables(args); ArgResults argResults; @@ -127,10 +158,12 @@ } if (argResults.wasParsed('sound-null-safety')) { var soundNullSafety = argResults['sound-null-safety'] as bool; - print('Dart 3 only supports sound null safety, ' - 'see https://dart.dev/null-safety.\n' - 'The `--sound-null-safety` flag is ignored ' - 'and will be removed in a future version.'); + print( + 'Dart 3 only supports sound null safety, ' + 'see https://dart.dev/null-safety.\n' + 'The `--sound-null-safety` flag is ignored ' + 'and will be removed in a future version.', + ); if (!soundNullSafety) { return CompilerResult(64); } @@ -139,12 +172,16 @@ var outPaths = argResults['out'] as List<String>; var moduleFormats = parseModuleFormatOption(argResults); if (outPaths.isEmpty) { - print('Please specify the output file location. For example:\n' - ' -o PATH/TO/OUTPUT_FILE.js'); + print( + 'Please specify the output file location. For example:\n' + ' -o PATH/TO/OUTPUT_FILE.js', + ); return CompilerResult(64); } else if (outPaths.length != moduleFormats.length) { - print('Number of output files (${outPaths.length}) must match ' - 'number of module formats (${moduleFormats.length}).'); + print( + 'Number of output files (${outPaths.length}) must match ' + 'number of module formats (${moduleFormats.length}).', + ); return CompilerResult(64); } @@ -154,8 +191,10 @@ } var options = Options.fromArguments(argResults); - addGeneratedVariables(declaredVariables, - enableAsserts: options.enableAsserts); + addGeneratedVariables( + declaredVariables, + enableAsserts: options.enableAsserts, + ); Uri toCustomUri(Uri uri) { if (!uri.hasScheme) { @@ -190,8 +229,9 @@ if (multiRootOutputPath == null) { if (outPaths.length > 1) { print( - 'If multiple output files (found ${outPaths.length}) are specified, ' - 'then --multi-root-output-path must be explicitly provided.'); + 'If multiple output files (found ${outPaths.length}) are specified, ' + 'then --multi-root-output-path must be explicitly provided.', + ); return CompilerResult(64); } var jsOutputUri = sourcePathToUri(p.absolute(outPaths.first)); @@ -199,11 +239,15 @@ } var fileSystem = MultiRootFileSystem( - options.multiRootScheme, multiRootPaths, fe.StandardFileSystem.instance); + options.multiRootScheme, + multiRootPaths, + fe.StandardFileSystem.instance, + ); var summaryPaths = options.summaryModules.keys.toList(); var summaryModules = Map.fromIterables( - summaryPaths.map(sourcePathToUri).cast<Uri>(), - options.summaryModules.values); + summaryPaths.map(sourcePathToUri).cast<Uri>(), + options.summaryModules.values, + ); var sdkSummaryPath = argResults['dart-sdk-summary'] as String?; var librarySpecPath = argResults['libraries-file'] as String?; var compileSdk = argResults['compile-sdk'] == true; @@ -215,7 +259,8 @@ // Compiling without manually passing or getting a default SDK summary is // only allowed when `compileSdk` is true. } - var invalidSummary = summaryPaths.any((s) => !s.endsWith('.dill')) || + var invalidSummary = + summaryPaths.any((s) => !s.endsWith('.dill')) || (sdkSummaryPath != null && !sdkSummaryPath.endsWith('.dill')); if (invalidSummary) { throw StateError('Non-dill file detected in input: $summaryPaths'); @@ -232,11 +277,14 @@ // // Another option: we could make an in-memory file with the relevant info. librarySpecPath = p.join( - p.dirname(p.dirname(sdkSummaryPath ?? defaultSdkSummaryPath)), - 'libraries.json'); + p.dirname(p.dirname(sdkSummaryPath ?? defaultSdkSummaryPath)), + 'libraries.json', + ); if (!File(librarySpecPath).existsSync()) { librarySpecPath = p.join( - p.dirname(sdkSummaryPath ?? defaultSdkSummaryPath), 'libraries.json'); + p.dirname(sdkSummaryPath ?? defaultSdkSummaryPath), + 'libraries.json', + ); } } @@ -264,8 +312,11 @@ fe.printDiagnosticMessage(message, print); } - var explicitExperimentalFlags = fe.parseExperimentalFlags(options.experiments, - onError: stderr.writeln, onWarning: print); + var explicitExperimentalFlags = fe.parseExperimentalFlags( + options.experiments, + onError: stderr.writeln, + onWarning: print, + ); var trackWidgetCreation = argResults['track-widget-creation'] as bool; var oldCompilerState = compilerState; @@ -280,18 +331,18 @@ // SDK and summaries. if (!useIncrementalCompiler) { compilerState = fe.initializeCompiler( - oldCompilerState, - compileSdk, - sourcePathToUri(getSdkPath()), - compileSdk ? null : sourcePathToUri(sdkSummaryPath!), - packageFile != null ? sourcePathToUri(packageFile) : null, - sourcePathToUri(librarySpecPath), - additionalDills, - DevCompilerTarget( - TargetFlags(trackWidgetCreation: trackWidgetCreation)), - fileSystem: fileSystem, - explicitExperimentalFlags: explicitExperimentalFlags, - environmentDefines: declaredVariables); + oldCompilerState, + compileSdk, + sourcePathToUri(getSdkPath()), + compileSdk ? null : sourcePathToUri(sdkSummaryPath!), + packageFile != null ? sourcePathToUri(packageFile) : null, + sourcePathToUri(librarySpecPath), + additionalDills, + DevCompilerTarget(TargetFlags(trackWidgetCreation: trackWidgetCreation)), + fileSystem: fileSystem, + explicitExperimentalFlags: explicitExperimentalFlags, + environmentDefines: declaredVariables, + ); result = await fe.compile(compilerState, inputs, diagnosticMessageHandler); } else { // If digests weren't given and if not in worker mode, create fake data and @@ -308,44 +359,48 @@ inputDigests[uri] = const [0]; } } - var doneAdditionalDills = - List.filled(summaryModules.length, dummyComponent); + var doneAdditionalDills = List.filled( + summaryModules.length, + dummyComponent, + ); compilerState = await fe.initializeIncrementalCompiler( - oldCompilerState, - { - 'trackWidgetCreation=$trackWidgetCreation', - 'multiRootScheme=${fileSystem.markerScheme}', - 'multiRootRoots=${fileSystem.roots}', - }, - doneAdditionalDills, - compileSdk, - sourcePathToUri(getSdkPath()), - compileSdk ? null : sourcePathToUri(sdkSummaryPath!), - packageFile != null ? sourcePathToUri(packageFile) : null, - sourcePathToUri(librarySpecPath), - additionalDills, - inputDigests, - DevCompilerTarget( - TargetFlags(trackWidgetCreation: trackWidgetCreation)), - fileSystem: fileSystem, - explicitExperimentalFlags: explicitExperimentalFlags, - environmentDefines: declaredVariables, - trackNeededDillLibraries: recordUsedInputs); + oldCompilerState, + { + 'trackWidgetCreation=$trackWidgetCreation', + 'multiRootScheme=${fileSystem.markerScheme}', + 'multiRootRoots=${fileSystem.roots}', + }, + doneAdditionalDills, + compileSdk, + sourcePathToUri(getSdkPath()), + compileSdk ? null : sourcePathToUri(sdkSummaryPath!), + packageFile != null ? sourcePathToUri(packageFile) : null, + sourcePathToUri(librarySpecPath), + additionalDills, + inputDigests, + DevCompilerTarget(TargetFlags(trackWidgetCreation: trackWidgetCreation)), + fileSystem: fileSystem, + explicitExperimentalFlags: explicitExperimentalFlags, + environmentDefines: declaredVariables, + trackNeededDillLibraries: recordUsedInputs, + ); var incrementalCompiler = compilerState.incrementalCompiler!; var cachedSdkInput = compileSdk ? null : compilerState.workerInputCache![sourcePathToUri(sdkSummaryPath!)]; compilerState.options.onDiagnostic = diagnosticMessageHandler; var incrementalCompilerResult = await incrementalCompiler.computeDelta( - entryPoints: inputs, - fullComponent: true, - trackNeededDillLibraries: recordUsedInputs); + entryPoints: inputs, + fullComponent: true, + trackNeededDillLibraries: recordUsedInputs, + ); result = fe.DdcResult( - incrementalCompilerResult.component, - cachedSdkInput?.component, - doneAdditionalDills, - incrementalCompilerResult.classHierarchy, - incrementalCompilerResult.neededDillLibraries); + incrementalCompilerResult.component, + cachedSdkInput?.component, + doneAdditionalDills, + incrementalCompilerResult.classHierarchy, + incrementalCompilerResult.neededDillLibraries, + ); } compilerState.options.onDiagnostic = null; // See http://dartbug.com/36983. @@ -361,27 +416,37 @@ if (reloadDeltaKernel != null) { if (reloadLastAcceptedKernel != null) { final lastAcceptedComponent = Component(); - kernel.BinaryBuilder((await File(reloadLastAcceptedKernel).readAsBytes())) - .readComponent(lastAcceptedComponent); + kernel.BinaryBuilder( + (await File(reloadLastAcceptedKernel).readAsBytes()), + ).readComponent(lastAcceptedComponent); final deltaInspector = HotReloadDeltaInspector( - nonHotReloadablePackages: options.nonHotReloadablePackages); + nonHotReloadablePackages: options.nonHotReloadablePackages, + ); final rejectionReasons = deltaInspector.compareGenerations( - lastAcceptedComponent, compiledLibraries); + lastAcceptedComponent, + compiledLibraries, + ); if (rejectionReasons.isNotEmpty) { throw StateError( - 'Hot reload rejected due to:\n${rejectionReasons.join('\n')}\n' - 'Try performing a hot restart instead.'); + 'Hot reload rejected due to:\n${rejectionReasons.join('\n')}\n' + 'Try performing a hot restart instead.', + ); } } var sink = File(reloadDeltaKernel).openWrite(); - kernel.BinaryPrinter(sink, includeSources: false, includeSourceBytes: false) - .writeComponentFile(compiledLibraries); + kernel.BinaryPrinter( + sink, + includeSources: false, + includeSourceBytes: false, + ).writeComponentFile(compiledLibraries); await sink.flush(); await sink.close(); } else { if (reloadLastAcceptedKernel != null) { - throw ArgumentError("Must provide 'new-reload-delta-kernel' if " - "'old-reload-delta-kernel' provided."); + throw ArgumentError( + "Must provide 'new-reload-delta-kernel' if " + "'old-reload-delta-kernel' provided.", + ); } } @@ -390,8 +455,9 @@ if (argResults['summarize'] as bool) { if (outPaths.length > 1) { print( - 'If multiple output files (found ${outPaths.length}) are specified, ' - 'the --summarize option is not supported.'); + 'If multiple output files (found ${outPaths.length}) are specified, ' + 'the --summarize option is not supported.', + ); return CompilerResult(64); } // Note: CFE mutates the Kernel tree, so we can't save the dill @@ -413,8 +479,9 @@ if (argResults['experimental-output-compiled-kernel'] as bool) { if (outPaths.length > 1) { print( - 'If multiple output files (found ${outPaths.length}) are specified, ' - 'the --experimental-output-compiled-kernel option is not supported.'); + 'If multiple output files (found ${outPaths.length}) are specified, ' + 'the --experimental-output-compiled-kernel option is not supported.', + ); return CompilerResult(64); } // Note: CFE mutates the Kernel tree, so we can't save the dill @@ -434,15 +501,19 @@ if (argResults['summarize-text'] as bool) { if (outPaths.length > 1) { print( - 'If multiple output files (found ${outPaths.length}) are specified, ' - 'the --summarize-text option is not supported.'); + 'If multiple output files (found ${outPaths.length}) are specified, ' + 'the --summarize-text option is not supported.', + ); return CompilerResult(64); } var sb = StringBuffer(); kernel.Printer(sb).writeComponentFile(component); outFiles.add(File('${outPaths.first}.txt').writeAsString(sb.toString())); - outFiles.add(File('${outPaths.first.split('.')[0]}.ast.xml') - .writeAsString(DebugPrinter.prettyPrint(compiledLibraries))); + outFiles.add( + File( + '${outPaths.first.split('.')[0]}.ast.xml', + ).writeAsString(DebugPrinter.prettyPrint(compiledLibraries)), + ); } final importToSummary = Map<Library, Component>.identity(); @@ -470,10 +541,12 @@ continue; } final isDartLibrary = l.importUri.isScheme('dart'); - final resolvedModuleName = - isDartLibrary ? js_ast.dartSdkModule : options.moduleName; - final resolvedComponent = - isDartLibrary ? result.sdkSummary! : result.component; + final resolvedModuleName = isDartLibrary + ? js_ast.dartSdkModule + : options.moduleName; + final resolvedComponent = isDartLibrary + ? result.sdkSummary! + : result.component; importToSummary[l] = resolvedComponent; summaryToModule.putIfAbsent(resolvedComponent, () => resolvedModuleName); @@ -481,10 +554,20 @@ } var compiler = options.emitLibraryBundle - ? LibraryBundleCompiler(component, result.classHierarchy, options, - importToSummary, summaryToModule) - : ProgramCompiler(component, result.classHierarchy, options, - importToSummary, summaryToModule); + ? LibraryBundleCompiler( + component, + result.classHierarchy, + options, + importToSummary, + summaryToModule, + ) + : ProgramCompiler( + component, + result.classHierarchy, + options, + importToSummary, + summaryToModule, + ); var jsModule = compiler.emitModule(compiledLibraries); @@ -498,35 +581,37 @@ await file.parent.create(recursive: true); var mapUrl = p.toUri('$output.map').toString(); var jsCode = jsProgramToCode( - jsModule, - options.emitLibraryBundle - ? ModuleFormat.ddcLibraryBundle - : moduleFormat, - buildSourceMap: options.sourceMap, - inlineSourceMap: options.inlineSourceMap, - emitDebugMetadata: options.emitDebugMetadata, - emitDebugSymbols: options.emitDebugSymbols, - jsUrl: p.toUri(output).toString(), - mapUrl: mapUrl, - fullDillUri: fullDillUri, - customScheme: options.multiRootScheme, - multiRootOutputPath: multiRootOutputPath, - compiler: compiler, - component: compiledLibraries); + jsModule, + options.emitLibraryBundle ? ModuleFormat.ddcLibraryBundle : moduleFormat, + buildSourceMap: options.sourceMap, + inlineSourceMap: options.inlineSourceMap, + emitDebugMetadata: options.emitDebugMetadata, + emitDebugSymbols: options.emitDebugSymbols, + jsUrl: p.toUri(output).toString(), + mapUrl: mapUrl, + fullDillUri: fullDillUri, + customScheme: options.multiRootScheme, + multiRootOutputPath: multiRootOutputPath, + compiler: compiler, + component: compiledLibraries, + ); outFiles.add(file.writeAsString(jsCode.code)); if (jsCode.sourceMap != null) { outFiles.add( - File('$output.map').writeAsString(json.encode(jsCode.sourceMap))); + File('$output.map').writeAsString(json.encode(jsCode.sourceMap)), + ); } if (jsCode.metadata != null) { outFiles.add( - File('$output.metadata').writeAsString(json.encode(jsCode.metadata))); + File('$output.metadata').writeAsString(json.encode(jsCode.metadata)), + ); } if (jsCode.symbols != null) { outFiles.add( - File('$output.symbols').writeAsString(json.encode(jsCode.symbols))); + File('$output.symbols').writeAsString(json.encode(jsCode.symbols)), + ); } } @@ -535,13 +620,17 @@ if (useIncrementalCompiler) { var neededDillLibraries = result.neededDillLibraries!; compilerState.incrementalCompiler!.updateNeededDillLibrariesWithHierarchy( - neededDillLibraries, result.classHierarchy); + neededDillLibraries, + result.classHierarchy, + ); for (var lib in neededDillLibraries) { if (lib.importUri.isScheme('dart')) continue; var uri = compilerState.libraryToInputDill![lib.importUri]; if (uri == null) { - throw StateError('Library ${lib.importUri} was recorded as used, ' - 'but was not in the list of known libraries.'); + throw StateError( + 'Library ${lib.importUri} was recorded as used, ' + 'but was not in the list of known libraries.', + ); } usedOutlines.add(uri); } @@ -578,8 +667,10 @@ var inputs = argResults.rest.toList(); if (inputs.length != 1) { - print('Only a single input file is supported to compile the sdk from dill' - 'but found: \n${inputs.join('\n')}'); + print( + 'Only a single input file is supported to compile the sdk from dill' + 'but found: \n${inputs.join('\n')}', + ); return CompilerResult(64); } @@ -591,12 +682,16 @@ var outPaths = argResults['out'] as List<String>; var moduleFormats = parseModuleFormatOption(argResults); if (outPaths.isEmpty) { - print('Please specify the output file location. For example:\n' - ' -o PATH/TO/OUTPUT_FILE.js'); + print( + 'Please specify the output file location. For example:\n' + ' -o PATH/TO/OUTPUT_FILE.js', + ); return CompilerResult(64); } else if (outPaths.length != moduleFormats.length) { - print('Number of output files (${outPaths.length}) must match ' - 'number of module formats (${moduleFormats.length}).'); + print( + 'Number of output files (${outPaths.length}) must match ' + 'number of module formats (${moduleFormats.length}).', + ); return CompilerResult(64); } @@ -609,8 +704,10 @@ } if (invalidLibraries.isNotEmpty) { - print('Only the SDK libraries can be compiled from .dill but found:\n' - '${invalidLibraries.join('\n')}'); + print( + 'Only the SDK libraries can be compiled from .dill but found:\n' + '${invalidLibraries.join('\n')}', + ); return CompilerResult(64); } var coreTypes = CoreTypes(component); @@ -618,10 +715,22 @@ var options = Options.fromSdkRequiredArguments(argResults); var compiler = options.emitLibraryBundle - ? LibraryBundleCompiler(component, hierarchy, options, const {}, const {}, - coreTypes: coreTypes) - : ProgramCompiler(component, hierarchy, options, const {}, const {}, - coreTypes: coreTypes); + ? LibraryBundleCompiler( + component, + hierarchy, + options, + const {}, + const {}, + coreTypes: coreTypes, + ) + : ProgramCompiler( + component, + hierarchy, + options, + const {}, + const {}, + coreTypes: coreTypes, + ); var jsModule = compiler.emitModule(component); var outFiles = <Future>[]; @@ -634,22 +743,22 @@ var file = File(output); await file.parent.create(recursive: true); var jsCode = jsProgramToCode( - jsModule, - options.emitLibraryBundle - ? ModuleFormat.ddcLibraryBundle - : moduleFormat, - buildSourceMap: options.sourceMap, - inlineSourceMap: options.inlineSourceMap, - jsUrl: p.toUri(output).toString(), - mapUrl: p.toUri('$output.map').toString(), - customScheme: options.multiRootScheme, - multiRootOutputPath: options.multiRootOutputPath, - component: component); + jsModule, + options.emitLibraryBundle ? ModuleFormat.ddcLibraryBundle : moduleFormat, + buildSourceMap: options.sourceMap, + inlineSourceMap: options.inlineSourceMap, + jsUrl: p.toUri(output).toString(), + mapUrl: p.toUri('$output.map').toString(), + customScheme: options.multiRootScheme, + multiRootOutputPath: options.multiRootOutputPath, + component: component, + ); outFiles.add(file.writeAsString(jsCode.code)); if (jsCode.sourceMap != null) { outFiles.add( - File('$output.map').writeAsString(json.encode(jsCode.sourceMap))); + File('$output.map').writeAsString(json.encode(jsCode.sourceMap)), + ); } } await Future.wait(outFiles); @@ -724,21 +833,26 @@ /// /// See [placeSourceMap] for a description of [sourceMapBase], [customScheme], /// and [multiRootOutputPath] arguments. -JSCode jsProgramToCode(js_ast.Program moduleTree, ModuleFormat format, - {bool buildSourceMap = false, - bool inlineSourceMap = false, - bool emitDebugMetadata = false, - bool emitDebugSymbols = false, - String? jsUrl, - String? mapUrl, - String? fullDillUri, - String? sourceMapBase, - String? customScheme, - String? multiRootOutputPath, - Compiler? compiler, - Component? component}) { +JSCode jsProgramToCode( + js_ast.Program moduleTree, + ModuleFormat format, { + bool buildSourceMap = false, + bool inlineSourceMap = false, + bool emitDebugMetadata = false, + bool emitDebugSymbols = false, + String? jsUrl, + String? mapUrl, + String? fullDillUri, + String? sourceMapBase, + String? customScheme, + String? multiRootOutputPath, + Compiler? compiler, + Component? component, +}) { var opts = js_ast.JavaScriptPrintingOptions( - allowKeywordsInProperties: true, allowSingleLineIfStatements: true); + allowKeywordsInProperties: true, + allowSingleLineIfStatements: true, + ); js_ast.SimpleJavaScriptPrintingContext printer; SourceMapBuilder? sourceMap; if (buildSourceMap) { @@ -751,13 +865,23 @@ var tree = transformModuleFormat(format, moduleTree); var nameListener = emitDebugSymbols ? js_ast.NameListener() : null; - tree.accept(js_ast.Printer(opts, printer, - localNamer: js_ast.ScopedNamer(tree, nameListener))); + tree.accept( + js_ast.Printer( + opts, + printer, + localNamer: js_ast.ScopedNamer(tree, nameListener), + ), + ); Map<String, Object?>? builtMap; if (buildSourceMap && sourceMap != null) { - builtMap = placeSourceMap(sourceMap.build(jsUrl!), mapUrl!, customScheme, - multiRootOutputPath: multiRootOutputPath, sourceMapBase: sourceMapBase); + builtMap = placeSourceMap( + sourceMap.build(jsUrl!), + mapUrl!, + customScheme, + multiRootOutputPath: multiRootOutputPath, + sourceMapBase: sourceMapBase, + ); var jsDir = p.dirname(p.fromUri(jsUrl)); var relative = p.relative(p.fromUri(mapUrl), from: jsDir); var relativeMapUrl = p.toUri(relative).toString(); @@ -769,8 +893,9 @@ var text = printer.getText(); var encodedMap = json.encode(builtMap); - var rawSourceMap = - inlineSourceMap ? js.escapedString(encodedMap, "'").value : 'null'; + var rawSourceMap = inlineSourceMap + ? js.escapedString(encodedMap, "'").value + : 'null'; text = text.replaceFirst(ProgramCompiler.sourceMapLocationID, rawSourceMap); // This is intended to be used by our build/debug tools to gather metrics. @@ -786,10 +911,12 @@ // compilation server, not the browser. We don't yet have the infra for that. var compileTimeStatistics = { 'dartSize': _computeDartSize(component!), - 'sourceMapSize': encodedMap.length + 'sourceMapSize': encodedMap.length, }; text = text.replaceFirst( - ProgramCompiler.metricsLocationID, '$compileTimeStatistics'); + ProgramCompiler.metricsLocationID, + '$compileTimeStatistics', + ); var debugMetadata = emitDebugMetadata ? _emitMetadata(moduleTree, component, mapUrl!, jsUrl!, fullDillUri) @@ -797,7 +924,11 @@ var debugSymbols = emitDebugSymbols ? _emitSymbols( - compiler!, moduleTree.name!, nameListener!.identifierNames, component) + compiler!, + moduleTree.name!, + nameListener!.identifierNames, + component, + ) : null; return JSCode(text, builtMap, symbols: debugSymbols, metadata: debugMetadata); @@ -809,14 +940,20 @@ /// Uses information from the [compiler] used to compile the JS module combined /// with [identifierNames] that maps JavaScript identifier nodes to their actual /// names used when outputting the JavaScript. -ModuleSymbols _emitSymbols(Compiler compiler, String moduleName, - Map<js_ast.Identifier, String> identifierNames, Component component) { +ModuleSymbols _emitSymbols( + Compiler compiler, + String moduleName, + Map<js_ast.Identifier, String> identifierNames, + Component component, +) { /// Returns the name selected in the final JavaScript for [id]. String lookupName(js_ast.Identifier id) { var name = identifierNames[id]; if (name == null) { - throw Exception('No recorded naming decision found for Identifier with ' - 'name: ${id.name}'); + throw Exception( + 'No recorded naming decision found for Identifier with ' + 'name: ${id.name}', + ); } return name; } @@ -833,22 +970,39 @@ e.key: lookupName(e.value), }; - return ModuleSymbolsCollector(moduleName, classJsNames, compiler.memberNames, - procedureJsNames, variableJsNames) - .collectSymbolInfo(component); + return ModuleSymbolsCollector( + moduleName, + classJsNames, + compiler.memberNames, + procedureJsNames, + variableJsNames, + ).collectSymbolInfo(component); } -ModuleMetadata _emitMetadata(js_ast.Program program, Component component, - String sourceMapUri, String moduleUri, String? fullDillUri) { - var metadata = ModuleMetadata(program.name!, loadFunctionName(program.name!), - sourceMapUri, moduleUri, fullDillUri); +ModuleMetadata _emitMetadata( + js_ast.Program program, + Component component, + String sourceMapUri, + String moduleUri, + String? fullDillUri, +) { + var metadata = ModuleMetadata( + program.name!, + loadFunctionName(program.name!), + sourceMapUri, + moduleUri, + fullDillUri, + ); for (var lib in component.libraries) { - metadata.addLibrary(LibraryMetadata( + metadata.addLibrary( + LibraryMetadata( libraryUriToJsIdentifier(lib.importUri), lib.importUri.toString(), lib.fileUri.toString(), - [...lib.parts.map((p) => p.partUri)])); + [...lib.parts.map((p) => p.partUri)], + ), + ); } return metadata; } @@ -890,15 +1044,21 @@ } /// Adds all synthesized environment variables to [variables]. -Map<String, String> addGeneratedVariables(Map<String, String> variables, - {required bool enableAsserts}) { +Map<String, String> addGeneratedVariables( + Map<String, String> variables, { + required bool enableAsserts, +}) { variables['dart.web.assertions_enabled'] = '$enableAsserts'; return variables; } /// The default path of the kernel summary for the Dart SDK. -final defaultSdkSummaryPath = - p.join(getSdkPath(), 'lib', '_internal', 'ddc_outline.dill'); +final defaultSdkSummaryPath = p.join( + getSdkPath(), + 'lib', + '_internal', + 'ddc_outline.dill', +); final defaultLibrarySpecPath = p.join(getSdkPath(), 'lib', 'libraries.json'); @@ -906,8 +1066,9 @@ String getSdkPath() { // Support explicit sdk location through an environment variable. var resolvedExecutable = Platform.environment['resolvedExecutable']; - return p - .dirname(p.dirname(resolvedExecutable ?? Platform.resolvedExecutable)); + return p.dirname( + p.dirname(resolvedExecutable ?? Platform.resolvedExecutable), + ); } /// Returns the absolute path to the default `package_config.json` file, or @@ -1005,9 +1166,13 @@ // TODO(#40251): Remove this logic from dev_compiler itself, push it to the // invokers of dev_compiler which have more knowledge about how they want // source paths to look. -Map<String, Object?> placeSourceMap(Map<String, Object?> sourceMap, - String sourceMapPath, String? multiRootScheme, - {String? multiRootOutputPath, String? sourceMapBase}) { +Map<String, Object?> placeSourceMap( + Map<String, Object?> sourceMap, + String sourceMapPath, + String? multiRootScheme, { + String? multiRootOutputPath, + String? sourceMapBase, +}) { var map = Map.of(sourceMap); // Convert to a local file path if it's not. sourceMapPath = sourcePathToUri(p.absolute(p.fromUri(sourceMapPath))).path; @@ -1025,8 +1190,9 @@ // like dart2js. var shortPath = uri.path.replaceAll('/sdk/', '/dart-sdk/'); var multiRootPath = "${multiRootOutputPath ?? ''}$shortPath"; - multiRootPath = p.url - .joinAll(p.split(p.relative(multiRootPath, from: sourceMapDir))); + multiRootPath = p.url.joinAll( + p.split(p.relative(multiRootPath, from: sourceMapDir)), + ); return multiRootPath; } return sourcePath; @@ -1048,7 +1214,8 @@ list[i] = makeRelative(list[i] as String); } map['sources'] = list; - map['file'] = - map['file'] != null ? makeRelative(map['file'] as String) : null; + map['file'] = map['file'] != null + ? makeRelative(map['file'] as String) + : null; return map; }
diff --git a/pkg/dev_compiler/lib/src/command/options.dart b/pkg/dev_compiler/lib/src/command/options.dart index 8604baa..e89596e 100644 --- a/pkg/dev_compiler/lib/src/command/options.dart +++ b/pkg/dev_compiler/lib/src/command/options.dart
@@ -109,142 +109,181 @@ /// The serialization mode to use for macro communication. final String? macroSerializationMode; - Options( - {this.sourceMap = true, - this.inlineSourceMap = false, - this.summarizeApi = true, - this.enableAsserts = true, - this.replCompile = false, - this.emitDebugMetadata = false, - this.emitDebugSymbols = false, - this.emitFullCompiledKernel = false, - this.reloadLastAcceptedKernel, - this.reloadDeltaKernel, - this.summaryModules = const {}, - this.nonHotReloadablePackages = const {}, - this.moduleFormats = const [], - required this.moduleName, - this.multiRootScheme = 'org-dartlang-app', - this.multiRootOutputPath, - this.experiments = const {}, - this.canaryFeatures = false, - this.dynamicModule = false, - this.precompiledMacros = const [], - this.macroSerializationMode}) - : emitLibraryBundle = canaryFeatures && + Options({ + this.sourceMap = true, + this.inlineSourceMap = false, + this.summarizeApi = true, + this.enableAsserts = true, + this.replCompile = false, + this.emitDebugMetadata = false, + this.emitDebugSymbols = false, + this.emitFullCompiledKernel = false, + this.reloadLastAcceptedKernel, + this.reloadDeltaKernel, + this.summaryModules = const {}, + this.nonHotReloadablePackages = const {}, + this.moduleFormats = const [], + required this.moduleName, + this.multiRootScheme = 'org-dartlang-app', + this.multiRootOutputPath, + this.experiments = const {}, + this.canaryFeatures = false, + this.dynamicModule = false, + this.precompiledMacros = const [], + this.macroSerializationMode, + }) : emitLibraryBundle = canaryFeatures && moduleFormats.length == 1 && moduleFormats.single == ModuleFormat.ddc; Options.fromArguments(ArgResults args) : this( - sourceMap: args['source-map'] as bool, - inlineSourceMap: args['inline-source-map'] as bool, - summarizeApi: args['summarize'] as bool, - enableAsserts: args['enable-asserts'] as bool, - replCompile: args['repl-compile'] as bool, - emitDebugMetadata: args['experimental-emit-debug-metadata'] as bool, - emitDebugSymbols: args['emit-debug-symbols'] as bool, - emitFullCompiledKernel: - args['experimental-output-compiled-kernel'] as bool, - reloadLastAcceptedKernel: - args['reload-last-accepted-kernel'] as String?, - reloadDeltaKernel: args['reload-delta-kernel'] as String?, - summaryModules: - _parseCustomSummaryModules(args['summary'] as List<String>), - moduleFormats: parseModuleFormatOption(args), - moduleName: _getModuleName(args), - multiRootScheme: args['multi-root-scheme'] as String, - multiRootOutputPath: args['multi-root-output-path'] as String?, - experiments: parseExperimentalArguments( - args['enable-experiment'] as List<String>), - canaryFeatures: args['canary'] as bool, - dynamicModule: args['dynamic-module'] as bool, - precompiledMacros: args['precompiled-macro'] as List<String>, - macroSerializationMode: - args['macro-serialization-mode'] as String?); + sourceMap: args['source-map'] as bool, + inlineSourceMap: args['inline-source-map'] as bool, + summarizeApi: args['summarize'] as bool, + enableAsserts: args['enable-asserts'] as bool, + replCompile: args['repl-compile'] as bool, + emitDebugMetadata: args['experimental-emit-debug-metadata'] as bool, + emitDebugSymbols: args['emit-debug-symbols'] as bool, + emitFullCompiledKernel: + args['experimental-output-compiled-kernel'] as bool, + reloadLastAcceptedKernel: + args['reload-last-accepted-kernel'] as String?, + reloadDeltaKernel: args['reload-delta-kernel'] as String?, + summaryModules: _parseCustomSummaryModules( + args['summary'] as List<String>, + ), + moduleFormats: parseModuleFormatOption(args), + moduleName: _getModuleName(args), + multiRootScheme: args['multi-root-scheme'] as String, + multiRootOutputPath: args['multi-root-output-path'] as String?, + experiments: parseExperimentalArguments( + args['enable-experiment'] as List<String>, + ), + canaryFeatures: args['canary'] as bool, + dynamicModule: args['dynamic-module'] as bool, + precompiledMacros: args['precompiled-macro'] as List<String>, + macroSerializationMode: args['macro-serialization-mode'] as String?, + ); Options.fromSdkRequiredArguments(ArgResults args) : this( - summarizeApi: false, - moduleFormats: parseModuleFormatOption(args), - // When compiling the SDK use dart_sdk as the default. This is the - // assumed name in various places around the build systems. - moduleName: - args['module-name'] != null ? _getModuleName(args) : 'dart_sdk', - multiRootScheme: args['multi-root-scheme'] as String, - multiRootOutputPath: args['multi-root-output-path'] as String?, - experiments: parseExperimentalArguments( - args['enable-experiment'] as List<String>), - canaryFeatures: args['canary'] as bool); + summarizeApi: false, + moduleFormats: parseModuleFormatOption(args), + // When compiling the SDK use dart_sdk as the default. This is the + // assumed name in various places around the build systems. + moduleName: + args['module-name'] != null ? _getModuleName(args) : 'dart_sdk', + multiRootScheme: args['multi-root-scheme'] as String, + multiRootOutputPath: args['multi-root-output-path'] as String?, + experiments: parseExperimentalArguments( + args['enable-experiment'] as List<String>, + ), + canaryFeatures: args['canary'] as bool, + ); static void addArguments(ArgParser parser, {bool hide = true}) { addSdkRequiredArguments(parser, hide: hide); parser - ..addMultiOption('summary', - abbr: 's', - help: 'API summary file(s) of imported libraries, optionally\n' - 'with module import path: -s path.dill=js/import/path') - ..addFlag('summarize', - help: 'Emit an API summary file.', defaultsTo: true, hide: hide) - ..addFlag('source-map', - help: 'Emit source mapping.', defaultsTo: true, hide: hide) - ..addFlag('inline-source-map', - help: 'Emit source mapping inline.', defaultsTo: false, hide: hide) - ..addFlag('enable-asserts', - help: 'Enable assertions.', defaultsTo: true, hide: hide) - ..addFlag('repl-compile', - help: 'Compile in a more permissive REPL mode, allowing access' - ' to private members across library boundaries. This should' - ' only be used by debugging tools.', - defaultsTo: false, - hide: hide) - // TODO(41852) Define a process for breaking changes before graduating from - // experimental. - ..addFlag('experimental-emit-debug-metadata', - help: 'Experimental option for compiler development.\n' - 'Output a metadata file for debug tools next to the .js output.', - defaultsTo: false, - hide: true) - ..addFlag('emit-debug-symbols', - help: 'Experimental option for compiler development.\n' - 'Output a symbols file for debug tools next to the .js output.', - defaultsTo: false, - hide: true) - ..addFlag('experimental-output-compiled-kernel', - help: 'Experimental option for compiler development.\n' - 'Output a full kernel file for currently compiled module next to ' - 'the .js output.', - defaultsTo: false, - hide: true) - ..addOption('reload-last-accepted-kernel', - help: 'Provides a file path to read a dill file. The enclosed kernel ' - 'will be diffed against the kernel produced by this compilation ' - 'as an incremental hot reload step.', - hide: true) - ..addOption('reload-delta-kernel', - help: 'Provides a file path to write a dill file to. The resulting ' - 'kernel can be passed to future compilations via ' - '`reload-last-accepted-kernel` to get incremental hot reload ' - 'checks.', - hide: true) - ..addMultiOption('precompiled-macro', - help: - 'Configuration for precompiled macro binaries or kernel files.\n' - 'The expected format of this option is as follows: ' - '<absolute-path-to-binary>;<macro-library-uri>\nFor example: ' - '--precompiled-macro="/path/to/compiled/macro;' - 'package:some_macro/some_macro.dart". Multiple library uris may be ' - 'passed as well (separated by semicolons).', - hide: true) - ..addOption('macro-serialization-mode', - help: 'The serialization mode for communicating with macros.', - allowed: ['bytedata', 'json'], - defaultsTo: 'bytedata') - ..addFlag('dynamic-module', - help: 'Compile to generate a dynamic module', - negatable: false, - defaultsTo: false); + ..addMultiOption( + 'summary', + abbr: 's', + help: 'API summary file(s) of imported libraries, optionally\n' + 'with module import path: -s path.dill=js/import/path', + ) + ..addFlag( + 'summarize', + help: 'Emit an API summary file.', + defaultsTo: true, + hide: hide, + ) + ..addFlag( + 'source-map', + help: 'Emit source mapping.', + defaultsTo: true, + hide: hide, + ) + ..addFlag( + 'inline-source-map', + help: 'Emit source mapping inline.', + defaultsTo: false, + hide: hide, + ) + ..addFlag( + 'enable-asserts', + help: 'Enable assertions.', + defaultsTo: true, + hide: hide, + ) + ..addFlag( + 'repl-compile', + help: 'Compile in a more permissive REPL mode, allowing access' + ' to private members across library boundaries. This should' + ' only be used by debugging tools.', + defaultsTo: false, + hide: hide, + ) + // TODO(41852) Define a process for breaking changes before graduating + // from experimental. + ..addFlag( + 'experimental-emit-debug-metadata', + help: 'Experimental option for compiler development.\n' + 'Output a metadata file for debug tools next to the .js output.', + defaultsTo: false, + hide: true, + ) + ..addFlag( + 'emit-debug-symbols', + help: 'Experimental option for compiler development.\n' + 'Output a symbols file for debug tools next to the .js output.', + defaultsTo: false, + hide: true, + ) + ..addFlag( + 'experimental-output-compiled-kernel', + help: 'Experimental option for compiler development.\n' + 'Output a full kernel file for currently compiled module next to ' + 'the .js output.', + defaultsTo: false, + hide: true, + ) + ..addOption( + 'reload-last-accepted-kernel', + help: 'Provides a file path to read a dill file. The enclosed kernel ' + 'will be diffed against the kernel produced by this compilation ' + 'as an incremental hot reload step.', + hide: true, + ) + ..addOption( + 'reload-delta-kernel', + help: 'Provides a file path to write a dill file to. The resulting ' + 'kernel can be passed to future compilations via ' + '`reload-last-accepted-kernel` to get incremental hot reload ' + 'checks.', + hide: true, + ) + ..addMultiOption( + 'precompiled-macro', + help: 'Configuration for precompiled macro binaries or kernel files.\n' + 'The expected format of this option is as follows: ' + '<absolute-path-to-binary>;<macro-library-uri>\nFor example: ' + '--precompiled-macro="/path/to/compiled/macro;' + 'package:some_macro/some_macro.dart". Multiple library uris may be ' + 'passed as well (separated by semicolons).', + hide: true, + ) + ..addOption( + 'macro-serialization-mode', + help: 'The serialization mode for communicating with macros.', + allowed: ['bytedata', 'json'], + defaultsTo: 'bytedata', + ) + ..addFlag( + 'dynamic-module', + help: 'Compile to generate a dynamic module', + negatable: false, + defaultsTo: false, + ); } /// Adds only the arguments used to compile the SDK from a full dill file. @@ -256,30 +295,43 @@ addModuleFormatOptions(parser, hide: hide); parser ..addMultiOption('out', abbr: 'o', help: 'Output file (required).') - ..addOption('module-name', - help: 'The output module name, used in some JS module formats.\n' - 'Defaults to the output file name (without .js).') - ..addOption('multi-root-scheme', - help: 'The custom scheme to indicate a multi-root uri.', - defaultsTo: 'org-dartlang-app') - ..addOption('multi-root-output-path', - help: 'Path to set multi-root files relative to when generating' - ' source-maps.', - hide: true) - ..addMultiOption('enable-experiment', - help: 'Enable/disable experimental language features.', hide: hide) - ..addFlag('sound-null-safety', - help: 'Ignored and will be removed in a future version. ' - 'Sound null safety is always used.', - negatable: false, - defaultsTo: true) - ..addFlag('canary', - help: 'Enable all compiler features under active development. ' - 'This option is intended for compiler development only. ' - 'Canary features are likely to be unstable and can be removed ' - 'without warning.', - defaultsTo: false, - hide: true); + ..addOption( + 'module-name', + help: 'The output module name, used in some JS module formats.\n' + 'Defaults to the output file name (without .js).', + ) + ..addOption( + 'multi-root-scheme', + help: 'The custom scheme to indicate a multi-root uri.', + defaultsTo: 'org-dartlang-app', + ) + ..addOption( + 'multi-root-output-path', + help: 'Path to set multi-root files relative to when generating' + ' source-maps.', + hide: true, + ) + ..addMultiOption( + 'enable-experiment', + help: 'Enable/disable experimental language features.', + hide: hide, + ) + ..addFlag( + 'sound-null-safety', + help: 'Ignored and will be removed in a future version. ' + 'Sound null safety is always used.', + negatable: false, + defaultsTo: true, + ) + ..addFlag( + 'canary', + help: 'Enable all compiler features under active development. ' + 'This option is intended for compiler development only. ' + 'Canary features are likely to be unstable and can be removed ' + 'without warning.', + defaultsTo: false, + hide: true, + ); } static String _getModuleName(ArgResults args) { @@ -288,8 +340,9 @@ var outPaths = args['out'] as List<String>; if (outPaths.isEmpty) { throw UnsupportedError( - 'No module name provided and unable to synthesize one without any ' - 'output paths.'); + 'No module name provided and unable to synthesize one without any ' + 'output paths.', + ); } var outPath = outPaths.first; moduleName = p.basenameWithoutExtension(outPath); @@ -309,8 +362,11 @@ /// A summary path can contain "=" followed by an explicit module name to /// allow working with summaries whose physical location is outside of the /// module root directory. -Map<String, String> _parseCustomSummaryModules(List<String> summaryPaths, - [String? moduleRoot, String? summaryExt]) { +Map<String, String> _parseCustomSummaryModules( + List<String> summaryPaths, [ + String? moduleRoot, + String? summaryExt, +]) { var pathToModule = <String, String>{}; for (var summaryPath in summaryPaths) { var equalSign = summaryPath.indexOf('='); @@ -319,7 +375,8 @@ ? summaryPath.substring( 0, // Strip off the extension, including the last `.`. - summaryPath.length - (summaryExt.length + 1)) + summaryPath.length - (summaryExt.length + 1), + ) : p.withoutExtension(summaryPath); if (equalSign != -1) { modulePath = summaryPath.substring(equalSign + 1); @@ -327,7 +384,8 @@ } else if (moduleRoot != null && p.isWithin(moduleRoot, summaryPath)) { // TODO: Determine if this logic is still needed. modulePath = p.url.joinAll( - p.split(p.relative(summaryPathWithoutExt, from: moduleRoot))); + p.split(p.relative(summaryPathWithoutExt, from: moduleRoot)), + ); } else { modulePath = p.basename(summaryPathWithoutExt); }
diff --git a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart index 0cad4b7..7abf9fe 100644 --- a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart +++ b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
@@ -100,8 +100,10 @@ // Because `x` is a declaration, we know it is safe to move. // (see also _toAssign) var statements = body - .map((e) => - e == body.last ? e.toVariableDeclaration(name) : e.toStatement()) + .map( + (e) => + e == body.last ? e.toVariableDeclaration(name) : e.toStatement(), + ) .toList(); return _finishStatement(statements); } @@ -170,10 +172,13 @@ var bodyInstantiators = body.map(visitor.visit); return (args) => MetaLet( - Map.fromIterables(variables.keys, - valueInstantiators.map((i) => i(args) as Expression)), - bodyInstantiators.map((i) => i(args) as Expression).toList(), - statelessResult: statelessResult); + Map.fromIterables( + variables.keys, + valueInstantiators.map((i) => i(args) as Expression), + ), + bodyInstantiators.map((i) => i(args) as Expression).toList(), + statelessResult: statelessResult, + ); } Expression _toInvokedFunction(Block block) { @@ -216,7 +221,7 @@ initializers.length == 1 ? first.value!.toVariableDeclaration(first.declaration) : VariableDeclarationList('let', initializers).toStatement(), - node + node, ]); } return node; @@ -235,8 +240,11 @@ /// /// result = ((_) => _.addAll(result), _.add(2), _)([]) /// - MetaLet? _simplifyAssignment(Identifier left, - {String? op, bool isDeclaration = false}) { + MetaLet? _simplifyAssignment( + Identifier left, { + String? op, + bool isDeclaration = false, + }) { // See if the result value is a let* temporary variable. var result = body.last; if (result is MetaLetVariable && variables.containsKey(result)) { @@ -251,8 +259,9 @@ // Technically, putting one of these in a comma expression is not // legal. However when isDeclaration is true, toStatement will be // called immediately on the MetaLet, which results in legal JS. - assign = VariableDeclarationList( - 'let', [VariableInitialization(left, value)]); + assign = VariableDeclarationList('let', [ + VariableInitialization(left, value), + ]); } else { assign = value.toAssignExpression(left, op); } @@ -260,8 +269,11 @@ assert(body.isNotEmpty); var newBody = Expression.binary([assign, ...body], ',') as Binary; newBody = _substitute(newBody, {result: left}); - return MetaLet(vars, newBody.commaToExpressionList(), - statelessResult: statelessResult); + return MetaLet( + vars, + newBody.commaToExpressionList(), + statelessResult: statelessResult, + ); } return null; } @@ -269,15 +281,20 @@ /// Similar to [Template.instantiate] but works with free variables. T _substitute<T extends Node>( - T tree, Map<MetaLetVariable, Expression> substitutions) { + T tree, + Map<MetaLetVariable, Expression> substitutions, +) { var generator = InstantiatorGeneratorVisitor(/*forceCopy:*/ false); var instantiator = generator.compile(tree); var nodes = List<MetaLetVariable>.from( - generator.analysis.containsInterpolatedNode.whereType<MetaLetVariable>()); + generator.analysis.containsInterpolatedNode.whereType<MetaLetVariable>(), + ); if (nodes.isEmpty) return tree; - return instantiator( - {for (var v in nodes) v.nameOrPosition: substitutions[v] ?? v}) as T; + return instantiator({ + for (var v in nodes) v.nameOrPosition: substitutions[v] ?? v, + }) + as T; } /// A temporary variable used in a [MetaLet].
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart index c9be0e2..7dfd18a 100644 --- a/pkg/dev_compiler/lib/src/compiler/js_names.dart +++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -45,9 +45,9 @@ ScopedId(super.name, {this.needsCapture = false}) : _id = _idCounter++; ScopedId.from(ScopedId other) - : _id = other._id, - needsCapture = other.needsCapture, - super(other.name); + : _id = other._id, + needsCapture = other.needsCapture, + super(other.name); @override int get hashCode => _id; @@ -69,7 +69,7 @@ final Expression name; MaybeQualifiedId(this.qualifier, this.name) - : _expr = PropertyAccess(qualifier, name); + : _expr = PropertyAccess(qualifier, name); /// Helper to create an [Identifier] from something that starts as a property. static Identifier identifier(LiteralString propertyName) => @@ -124,7 +124,7 @@ final NameListener? _nameListener; ScopedNamer(Node node, [this._nameListener]) - : _scope = _RenameVisitor.build(node).rootScope; + : _scope = _RenameVisitor.build(node).rootScope; @override String getName(Identifier node) { @@ -219,9 +219,11 @@ if (rename) { usedIn = pendingRenames.putIfAbsent(id, () => HashSet()); } - for (var s = scope, end = declScope.parent; - s != end && s != null; - s = s.parent) { + for ( + var s = scope, end = declScope.parent; + s != end && s != null; + s = s.parent + ) { if (usedIn != null) { usedIn.add(s); } else { @@ -285,9 +287,11 @@ // TODO(jmesserly): what's the most readable scheme here? Maybe 1-letter // names in some cases? candidate = name == 'function' ? 'func' : '$name\$'; - for (var i = 0; - scopes.any((scope) => scope.used.contains(candidate)); - i++) { + for ( + var i = 0; + scopes.any((scope) => scope.used.contains(candidate)); + i++ + ) { candidate = '$name\$$i'; } } @@ -398,7 +402,7 @@ '__lookupGetter__', '__defineSetter__', '__lookupSetter__', - '__proto__' + '__proto__', }; /// Returns the JS member name for a public Dart instance member, before it @@ -489,9 +493,11 @@ if (path.startsWith('/') || path.startsWith('\\')) { path = path.substring(1, path.length); } - return toJSIdentifier(path - .replaceAll('\\', '__') - .replaceAll('/', '__') - .replaceAll('..', '__') - .replaceAll('-', '_')); + return toJSIdentifier( + path + .replaceAll('\\', '__') + .replaceAll('/', '__') + .replaceAll('..', '__') + .replaceAll('-', '_'), + ); }
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart index 2742c99..380dce4 100644 --- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart +++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -40,12 +40,14 @@ 'ddc': ModuleFormat.ddc, // Deprecated: 'node': ModuleFormat.common, - 'legacy': ModuleFormat.ddc + 'legacy': ModuleFormat.ddc, }; var selected = formats[s]; if (selected == null) { - throw ArgumentError('Invalid module format `$s`, allowed formats are: ' - '`${formats.keys.join(', ')}`'); + throw ArgumentError( + 'Invalid module format `$s`, allowed formats are: ' + '`${formats.keys.join(', ')}`', + ); } return selected; } @@ -59,21 +61,25 @@ /// [allowMultiple] formats to be specified, with each emitted into a separate /// file. void addModuleFormatOptions(ArgParser argParser, {bool hide = true}) { - argParser.addMultiOption('modules', help: 'module pattern to emit', allowed: [ - 'es6', - 'common', - 'amd', - 'ddc', - 'legacy', // renamed to ddc - 'node', // renamed to commonjs - 'all' // to emit all flavors for the SDK - ], allowedHelp: { - 'es6': 'ECMAScript 6 modules', - 'common': 'CommonJS/Node.js modules', - 'amd': 'AMD/RequireJS modules' - }, defaultsTo: [ - 'amd' - ]); + argParser.addMultiOption( + 'modules', + help: 'module pattern to emit', + allowed: [ + 'es6', + 'common', + 'amd', + 'ddc', + 'legacy', // renamed to ddc + 'node', // renamed to commonjs + 'all', // to emit all flavors for the SDK + ], + allowedHelp: { + 'es6': 'ECMAScript 6 modules', + 'common': 'CommonJS/Node.js modules', + 'amd': 'AMD/RequireJS modules', + }, + defaultsTo: ['amd'], + ); } /// Transforms an ES6 [module] into a given module [format]. @@ -108,18 +114,24 @@ /// Returns a new function that combines all statements from transformed imports /// from [items] and the body of the [function]. Fun transformFunctionModuleFormat( - List<ModuleItem> items, Fun function, ModuleFormat format) { + List<ModuleItem> items, + Fun function, + ModuleFormat format, +) { switch (format) { case ModuleFormat.ddc: return DdcModuleBuilder().buildFunctionWithImports(items, function); case ModuleFormat.amd: return AmdModuleBuilder().buildFunctionWithImports(items, function); case ModuleFormat.ddcLibraryBundle: - return DdcLibraryBundleBuilder() - .buildFunctionWithImports(items, function); + return DdcLibraryBundleBuilder().buildFunctionWithImports( + items, + function, + ); default: throw UnsupportedError( - 'Incremental build does not support $format module format'); + 'Incremental build does not support $format module format', + ); } } @@ -184,13 +196,19 @@ /// Used to load modules referenced in the expression during expression /// evaluation. static Statement buildLoadModule( - Identifier moduleVar, ImportDeclaration import) => - js.statement( - 'const # = dart_library.import(#);', [moduleVar, import.from]); + Identifier moduleVar, + ImportDeclaration import, + ) => js.statement('const # = dart_library.import(#);', [ + moduleVar, + import.from, + ]); /// Build library variable definitions for all libraries from [import]. static List<Statement> buildImports( - Identifier moduleVar, ImportDeclaration import, bool deferModules) { + Identifier moduleVar, + ImportDeclaration import, + bool deferModules, + ) { var items = <Statement>[]; for (var importName in import.namedImports!) { @@ -201,12 +219,15 @@ var asName = importName.asName ?? importName.name; if (deferModules && import.from.valueWithoutQuotes != dartSdkModule) { // Load non-SDK modules on demand (i.e., deferred). - items.add(js.statement( + items.add( + js.statement( 'let # = dart_library.defer(#, #, function (mod, lib) {' ' # = mod;' ' # = lib;' '});', - [asName, moduleVar, js.string(fromName), moduleVar, asName])); + [asName, moduleVar, js.string(fromName), moduleVar, asName], + ), + ); } else { items.add(js.statement('const # = #.#', [asName, moduleVar, fromName])); } @@ -216,7 +237,9 @@ /// Build statements for [exports]. static List<Statement> buildExports( - Identifier exportsVar, List<ExportDeclaration> exports) { + Identifier exportsVar, + List<ExportDeclaration> exports, + ) { var items = <Statement>[]; if (exports.isNotEmpty) { @@ -229,7 +252,8 @@ for (var name in names) { var alias = name.asName ?? name.name!; items.add( - js.statement('#.# = #;', [exportsVar, alias.name, name.name])); + js.statement('#.# = #;', [exportsVar, alias.name, name.name]), + ); } } } @@ -291,17 +315,20 @@ var moduleName = module.name!; var resultModule = NamedFunction( - loadFunctionIdentifier(moduleName), - js.fun("function(#) { 'use strict'; #; }", [parameters, statements]), - true); + loadFunctionIdentifier(moduleName), + js.fun("function(#) { 'use strict'; #; }", [parameters, statements]), + true, + ); var moduleDef = js.statement('dart_library.library(#, #, #, #, #)', [ js.string(moduleName, "'"), LiteralNull(), js.commentExpression( - 'Imports', ArrayInitializer(importNames, multiline: true)), + 'Imports', + ArrayInitializer(importNames, multiline: true), + ), resultModule, - ProgramCompiler.metricsLocationID + ProgramCompiler.metricsLocationID, ]); return Program(<ModuleItem>[...module.header, moduleDef]); } @@ -310,19 +337,19 @@ /// Generates CommonJS modules (used by Node.js). class CommonJSModuleBuilder extends _ModuleBuilder { Program build(Program module) { - var importStatements = [ - js.statement("'use strict';"), - ]; + var importStatements = [js.statement("'use strict';")]; // Collect imports/exports/statements. visitProgram(module); for (var import in imports) { // TODO(jmesserly): we could use destructuring here. - var moduleVar = - ScopedId(pathToJSIdentifier(import.from.valueWithoutQuotes)); - importStatements - .add(js.statement('const # = require(#);', [moduleVar, import.from])); + var moduleVar = ScopedId( + pathToJSIdentifier(import.from.valueWithoutQuotes), + ); + importStatements.add( + js.statement('const # = require(#);', [moduleVar, import.from]), + ); // TODO(jmesserly): optimize for the common case of a single import. for (var importName in import.namedImports!) { @@ -332,7 +359,8 @@ var libraryName = importName.name!.name; var asName = importName.asName ?? importName.name; importStatements.add( - js.statement('const # = #.#', [asName, moduleVar, libraryName])); + js.statement('const # = #.#', [asName, moduleVar, libraryName]), + ); } } statements.insertAll(0, importStatements); @@ -347,7 +375,8 @@ for (var name in names) { var alias = name.asName ?? name.name!; statements.add( - js.statement('#.# = #;', [exportsVar, alias.name, name.name])); + js.statement('#.# = #;', [exportsVar, alias.name, name.name]), + ); } } } @@ -365,12 +394,15 @@ /// Used to load modules referenced in the expression during expression /// evaluation. static Statement buildLoadModule( - Identifier moduleVar, ImportDeclaration import) => - js.statement('const # = require(#);', [moduleVar, import.from]); + Identifier moduleVar, + ImportDeclaration import, + ) => js.statement('const # = require(#);', [moduleVar, import.from]); /// Build library variable definitions for all libraries from [import]. static List<Statement> buildImports( - Identifier moduleVar, ImportDeclaration import) { + Identifier moduleVar, + ImportDeclaration import, + ) { var items = <Statement>[]; for (var importName in import.namedImports!) { @@ -379,8 +411,9 @@ var libraryName = importName.name!.name; var asName = importName.asName ?? importName.name; - items - .add(js.statement('const # = #.#', [asName, moduleVar, libraryName])); + items.add( + js.statement('const # = #.#', [asName, moduleVar, libraryName]), + ); } return items; } @@ -458,11 +491,14 @@ statements.addAll(buildExports(exports)); var resultModule = NamedFunction( - loadFunctionIdentifier(module.name!), - js.fun("function(#) { 'use strict'; #; }", [fnParams, statements]), - true); - var block = js.statement( - 'define(#, #);', [ArrayInitializer(dependencies), resultModule]); + loadFunctionIdentifier(module.name!), + js.fun("function(#) { 'use strict'; #; }", [fnParams, statements]), + true, + ); + var block = js.statement('define(#, #);', [ + ArrayInitializer(dependencies), + resultModule, + ]); return Program([...module.header, block]); } @@ -473,7 +509,9 @@ class DdcLibraryBundleBuilder extends _ModuleBuilder { /// Build library variable definitions for all libraries from [import]. static List<Statement> buildImports( - Identifier? moduleVar, ImportDeclaration import) { + Identifier? moduleVar, + ImportDeclaration import, + ) { var items = <Statement>[]; var fromName = import.from; @@ -484,13 +522,20 @@ var asName = importName.asName ?? importName.name; if (import.from.valueWithoutQuotes != dartSdkModule) { // Load non-SDK modules on demand (i.e., deferred). - items.add(js.statement( + items.add( + js.statement( 'let # = dartDevEmbedder.importLibrary(#, function (lib) { ' '# = lib; });', - [asName, fromName, asName])); + [asName, fromName, asName], + ), + ); } else { - items.add(js.statement( - 'const # = dartDevEmbedder.importLibrary(#)', [asName, fromName])); + items.add( + js.statement('const # = dartDevEmbedder.importLibrary(#)', [ + asName, + fromName, + ]), + ); } } return items; @@ -528,9 +573,10 @@ // TODO(nshahan): Delete and update the argument type when this is the // only supported module format. throw ArgumentError.value( - module, - '`DdcLibraryBundleBuilder` requires `LibraryBundle`s as input to ' - '`.build()`.'); + module, + '`DdcLibraryBundleBuilder` requires `LibraryBundle`s as input to ' + '`.build()`.', + ); } var body = <ModuleItem>[]; // Collect imports/exports/statements. @@ -551,21 +597,26 @@ statements.insertAll(0, importStatements); // Package the library into an initialization function. var initFunction = NamedFunction( - loadFunctionIdentifier(library.name!), - js.fun("function(#) { 'use strict'; #; return #; }", - [library.librarySelfVar!, statements, library.librarySelfVar!]), - true); - var resultModule = js.statement('dartDevEmbedder.defineLibrary(#, #)', - [js.string(library.name!), initFunction]); + loadFunctionIdentifier(library.name!), + js.fun("function(#) { 'use strict'; #; return #; }", [ + library.librarySelfVar!, + statements, + library.librarySelfVar!, + ]), + true, + ); + var resultModule = js.statement('dartDevEmbedder.defineLibrary(#, #)', [ + js.string(library.name!), + initFunction, + ]); body.add(resultModule); } // The library bundle format only needs to keep track of source maps and // doesn't need the full `trackLibraries` call that other formats use. - var setSourceMap = - js.statement('dartDevEmbedder.debugger.setSourceMap(#, #)', [ - js.string(module.name!), - LibraryCompiler.sourceMapLocationID, - ]); + var setSourceMap = js.statement( + 'dartDevEmbedder.debugger.setSourceMap(#, #)', + [js.string(module.name!), LibraryCompiler.sourceMapLocationID], + ); // Append all library definitions into a single file. return Program([...module.header, ...body, setSourceMap]); } @@ -613,12 +664,14 @@ /// Group libraries from [imports] by modules. List<MapEntry<Identifier, ImportDeclaration>> _collectModuleImports( - List<ImportDeclaration> imports) { + List<ImportDeclaration> imports, +) { var result = <MapEntry<Identifier, ImportDeclaration>>[]; for (var import in imports) { // TODO(jmesserly): we could use destructuring once Atom supports it. - var moduleVar = - ScopedId(pathToJSIdentifier(import.from.valueWithoutQuotes)); + var moduleVar = ScopedId( + pathToJSIdentifier(import.from.valueWithoutQuotes), + ); result.add(MapEntry<Identifier, ImportDeclaration>(moduleVar, import)); }
diff --git a/pkg/dev_compiler/lib/src/compiler/module_containers.dart b/pkg/dev_compiler/lib/src/compiler/module_containers.dart index d090794..d7e8ba5 100644 --- a/pkg/dev_compiler/lib/src/compiler/module_containers.dart +++ b/pkg/dev_compiler/lib/src/compiler/module_containers.dart
@@ -75,8 +75,10 @@ ModuleItemContainer._(this.name, this.containerId); /// Creates an automatically sharding container backed by JS Objects. - factory ModuleItemContainer.asObject(String name, - {required String Function(K) keyToString}) { + factory ModuleItemContainer.asObject( + String name, { + required String Function(K) keyToString, + }) { return ModuleItemObjectContainer<K>(name, keyToString); } @@ -150,7 +152,7 @@ String Function(K) keyToString; ModuleItemObjectContainer(String name, this.keyToString) - : super._(name, js_ast.ScopedId(name)); + : super._(name, js_ast.ScopedId(name)); @override void operator []=(K key, js_ast.Expression value) { @@ -160,18 +162,25 @@ } // Create a unique name for K when emitted as a JS field. var fieldString = keyToString(key); - _nameFrequencies.update(fieldString, (v) { - fieldString += '\$${v + 1}'; - return v + 1; - }, ifAbsent: () { - // Avoid shadowing common JS properties. - if (js_ast.objectProperties.contains(fieldString)) { - fieldString += '\$'; - } - return 0; - }); + _nameFrequencies.update( + fieldString, + (v) { + fieldString += '\$${v + 1}'; + return v + 1; + }, + ifAbsent: () { + // Avoid shadowing common JS properties. + if (js_ast.objectProperties.contains(fieldString)) { + fieldString += '\$'; + } + return 0; + }, + ); moduleItems[key] = ModuleItemData( - containerId, js_ast.LiteralString("'$fieldString'"), value); + containerId, + js_ast.LiteralString("'$fieldString'"), + value, + ); if (length % 500 == 0) containerId = js_ast.ScopedId(name); } @@ -191,16 +200,22 @@ if (!containersToProperties.containsKey(v.id)) { containersToProperties[v.id] = <js_ast.Property>[]; } - containersToProperties[v.id]!.add(js_ast.Property( - v.jsKey, emitValue == null ? v.jsValue : emitValue(k, v))); + containersToProperties[v.id]!.add( + js_ast.Property( + v.jsKey, + emitValue == null ? v.jsValue : emitValue(k, v), + ), + ); }); if (containersToProperties.isEmpty) return []; var statements = <js_ast.Statement>[]; containersToProperties.forEach((containerId, properties) { - var containerObject = js_ast.ObjectInitializer(properties, - multiline: properties.length > 1); + var containerObject = js_ast.ObjectInitializer( + properties, + multiline: properties.length > 1, + ); statements.add(js.statement('var # = #', [containerId, containerObject])); }); @@ -226,8 +241,11 @@ moduleItems[key]!.jsValue = value; return; } - moduleItems[key] = - ModuleItemData(containerId, js_ast.LiteralNumber('$length'), value); + moduleItems[key] = ModuleItemData( + containerId, + js_ast.LiteralNumber('$length'), + value, + ); } @override @@ -258,8 +276,8 @@ js.statement('var # = Array(#).fill(#)', [ containerId, js_ast.LiteralNumber('${properties.length}'), - valueSet.first - ]) + valueSet.first, + ]), ]; } // Array containers are not sharded, as we do not expect to hit V8's @@ -267,8 +285,8 @@ return [ js.statement('var # = #', [ containerId, - js_ast.ArrayInitializer(properties, multiline: properties.length > 1) - ]) + js_ast.ArrayInitializer(properties, multiline: properties.length > 1), + ]), ]; } }
diff --git a/pkg/dev_compiler/lib/src/compiler/rewrite_async.dart b/pkg/dev_compiler/lib/src/compiler/rewrite_async.dart index a6974bf..4147190 100644 --- a/pkg/dev_compiler/lib/src/compiler/rewrite_async.dart +++ b/pkg/dev_compiler/lib/src/compiler/rewrite_async.dart
@@ -157,17 +157,23 @@ /// [bodyPrefix] will get prepended to the body of the rewritten function and /// any references to parameters within it will be replaced with the correct /// temporary ID for that parameter. - js_ast.Fun rewrite(js_ast.Fun node, Object? bodySourceInformation, - Object? exitSourceInformation, - {List<js_ast.Statement>? bodyPrefix}) { + js_ast.Fun rewrite( + js_ast.Fun node, + Object? bodySourceInformation, + Object? exitSourceInformation, { + List<js_ast.Statement>? bodyPrefix, + }) { _analysis = PreTranslationAnalysis(_unsupported, node)..analyze(); _scopeCollector = _ScopeCollector(_analysis)..collect(node); _outerLabelName = _freshLabelName('outer'); final rewrittenFunction = _rewriteFunction( - node, bodySourceInformation, exitSourceInformation, - bodyPrefix: bodyPrefix); + node, + bodySourceInformation, + exitSourceInformation, + bodyPrefix: bodyPrefix, + ); if (bodyPrefix != null) { // Prepend the body prefix to the start of the rewritten function. rewrittenFunction.body.statements.insertAll(0, bodyPrefix); @@ -176,8 +182,11 @@ } js_ast.Expression get _currentErrorHandler { - return js_ast.number(_handlerLabels[ - _jumpTargets.lastWhere((node) => _handlerLabels[node] != null)]!); + return js_ast.number( + _handlerLabels[_jumpTargets.lastWhere( + (node) => _handlerLabels[node] != null, + )]!, + ); } /// Generates a label name based on [originalName] with a suffix to @@ -255,9 +264,11 @@ /// This should be followed by a break for the goto to be executed. Use /// [_gotoAndBreak] or [_addGoto] for this. js_ast.Statement _setGotoVariable(int label, Object? sourceInformation) { - return js_ast.ExpressionStatement(js_ast - .js('# = #', [_goto, js_ast.number(label)]).withSourceInformation( - sourceInformation)); + return js_ast.ExpressionStatement( + js_ast + .js('# = #', [_goto, js_ast.number(label)]) + .withSourceInformation(sourceInformation), + ); } /// Returns a block that has a goto to [label] including the break. @@ -271,11 +282,13 @@ statements.add(_setGotoVariable(label, sourceInformation)); if (insideUntranslatedBreakable) { hasJumpThoughOuterLabel = true; - statements.add(js_ast.Break(_outerLabelName) - .withSourceInformation(sourceInformation)); + statements.add( + js_ast.Break(_outerLabelName).withSourceInformation(sourceInformation), + ); } else { - statements - .add(js_ast.Break(null).withSourceInformation(sourceInformation)); + statements.add( + js_ast.Break(null).withSourceInformation(sourceInformation), + ); } return js_ast.Block(statements); } @@ -296,10 +309,13 @@ currentStatementBuffer.add(node); } - void _addExpressionStatement(js_ast.Expression node, - [Object? sourceInformation]) { - _addStatement(js_ast.ExpressionStatement(node) - ..sourceInformation = sourceInformation); + void _addExpressionStatement( + js_ast.Expression node, [ + Object? sourceInformation, + ]) { + _addStatement( + js_ast.ExpressionStatement(node)..sourceInformation = sourceInformation, + ); } /// True if there is an await or yield in [node] or some subexpression. @@ -309,7 +325,8 @@ Never _unsupported(js_ast.Node node) { throw UnsupportedError( - 'Node $node cannot be transformed by the await-sync transformer'); + 'Node $node cannot be transformed by the await-sync transformer', + ); } Never _unreachable(js_ast.Node node) { @@ -369,8 +386,10 @@ // TODO(sra): Many calls to this method use `store: false`, and could be // replaced with calls to `visitExpression`. T _withExpression<T>( - js_ast.Expression node, T Function(js_ast.Expression result) fn, - {required bool store}) { + js_ast.Expression node, + T Function(js_ast.Expression result) fn, { + required bool store, + }) { var visited = visitExpression(node); if (store) { visited = _storeIfNecessary(visited); @@ -405,9 +424,12 @@ /// cannot `bind` to a constructor tear-off as it would no longer be a /// constructor. However, constructors have no `this` context anyway so they /// are safe to tear-off without binding. - js_ast.Expression withCallTargetExpression(js_ast.Expression node, - js_ast.Expression Function(js_ast.Expression result) fn, - {required bool store, required bool isCall}) { + js_ast.Expression withCallTargetExpression( + js_ast.Expression node, + js_ast.Expression Function(js_ast.Expression result) fn, { + required bool store, + required bool isCall, + }) { var visited = visitExpression(node); js_ast.Expression storedIfNeeded; if (store) { @@ -415,14 +437,17 @@ final storedReceiver = _storeIfNecessary(visited.receiver); // We handle the `super` literal specially since the bound object in // that case is `this`. `super` cannot be passed to `bind`. - final bindTarget = - storedReceiver is js_ast.Super ? js_ast.This() : storedReceiver; + final bindTarget = storedReceiver is js_ast.Super + ? js_ast.This() + : storedReceiver; final jsTearOff = isCall ? js_ast.Call( js_ast.PropertyAccess.field( - js_ast.PropertyAccess(storedReceiver, visited.selector), - 'bind'), - [bindTarget]) + js_ast.PropertyAccess(storedReceiver, visited.selector), + 'bind', + ), + [bindTarget], + ) : visited; storedIfNeeded = _storeIfNecessary(jsTearOff); } else { @@ -444,11 +469,14 @@ /// an expression, visiting node2 it will output statements that /// might have an influence on the value of node1. js_ast.Expression withExpression2( - js_ast.Expression node1, - js_ast.Expression node2, - js_ast.Expression Function( - js_ast.Expression result1, js_ast.Expression result2) - fn) { + js_ast.Expression node1, + js_ast.Expression node2, + js_ast.Expression Function( + js_ast.Expression result1, + js_ast.Expression result2, + ) + fn, + ) { var r1 = visitExpression(node1); if (_shouldTransform(node2)) { r1 = _storeIfNecessary(r1); @@ -464,8 +492,10 @@ /// in temporary variables. /// /// See more explanation on [withExpression2]. - T withExpressions<T>(List<js_ast.Expression> nodes, - T Function(List<js_ast.Expression> results) fn) { + T withExpressions<T>( + List<js_ast.Expression> nodes, + T Function(List<js_ast.Expression> results) fn, + ) { var visited = <js_ast.Expression>[]; _collectVisited(nodes, visited); final result = fn(visited); @@ -474,8 +504,10 @@ /// Like [withExpressions], but permitting `null` nodes. If any of the nodes /// are null, they are ignored, and a null is passed to [fn] in that place. - T withNullableExpressions<T>(List<js_ast.Expression?> nodes, - T Function(List<js_ast.Expression?> results) fn) { + T withNullableExpressions<T>( + List<js_ast.Expression?> nodes, + T Function(List<js_ast.Expression?> results) fn, + ) { var visited = <js_ast.Expression?>[]; _collectVisited(nodes, visited); final result = fn(visited); @@ -483,7 +515,9 @@ } void _collectVisited( - List<js_ast.Expression?> nodes, List<js_ast.Expression?> visited) { + List<js_ast.Expression?> nodes, + List<js_ast.Expression?> visited, + ) { // Find last occurrence of a 'transform' expression in [nodes]. // All expressions before that must be stored in temp-vars. var lastTransformIndex = 0; @@ -530,7 +564,8 @@ nodeScope.isCaptured && nodeScope.hasDeclarations) { _addExpressionStatement( - js_ast.Assignment(nodeScope.scopeObject, _makeEmptyScopeObject())); + js_ast.Assignment(nodeScope.scopeObject, _makeEmptyScopeObject()), + ); } } @@ -550,14 +585,16 @@ /// Returns the rewritten function. js_ast.Fun _finishFunction( - List<js_ast.Parameter> parameters, - js_ast.Statement rewrittenBody, - js_ast.VariableDeclarationList variableDeclarationLists, - Object? functionSourceInformation, - Object? bodySourceInformation); + List<js_ast.Parameter> parameters, + js_ast.Statement rewrittenBody, + js_ast.VariableDeclarationList variableDeclarationLists, + Object? functionSourceInformation, + Object? bodySourceInformation, + ); Iterable<js_ast.VariableInitialization> variableInitializations( - Object? sourceInformation); + Object? sourceInformation, + ); /// Rewrites an async/sync*/async* function to a normal JavaScript function. /// @@ -697,9 +734,12 @@ /// [bodySourceInformation] is used on code generated to execute the function /// body and [exitSourceInformation] is used on code generated to exit the /// function. - js_ast.Fun _rewriteFunction(js_ast.Fun node, Object? bodySourceInformation, - Object? exitSourceInformation, - {List<js_ast.Statement>? bodyPrefix}) { + js_ast.Fun _rewriteFunction( + js_ast.Fun node, + Object? bodySourceInformation, + Object? exitSourceInformation, { + List<js_ast.Statement>? bodyPrefix, + }) { _beginLabel(_newLabel('Function start')); _handlerLabels[node] = _rethrowLabel; var body = node.body; @@ -710,10 +750,12 @@ var clauses = <js_ast.SwitchClause>[ for (final entry in labelledParts.entries) - js_ast.Case(js_ast.number(entry.key), js_ast.Block(entry.value)) + js_ast.Case(js_ast.number(entry.key), js_ast.Block(entry.value)), ]; - var rewrittenBody = js_ast.Switch(_goto, clauses) - .withSourceInformation(bodySourceInformation); + var rewrittenBody = js_ast.Switch( + _goto, + clauses, + ).withSourceInformation(bodySourceInformation); if (hasJumpThoughOuterLabel) { rewrittenBody = js_ast.LabeledStatement(_outerLabelName, rewrittenBody); } @@ -722,36 +764,67 @@ .withSourceInformation(bodySourceInformation); var variables = <js_ast.VariableInitialization>[]; - variables.add(_makeVariableInitializer( + variables.add( + _makeVariableInitializer( _goto, js_ast.number(0).withSourceInformation(bodySourceInformation), - bodySourceInformation)); + bodySourceInformation, + ), + ); variables.addAll(variableInitializations(bodySourceInformation)); if (_hasHandlerLabels) { - variables.add(_makeVariableInitializer( - _handler, js_ast.number(_rethrowLabel), bodySourceInformation)); - variables.add(_makeVariableInitializer(_errorStack, - js_ast.ArrayInitializer(const []), bodySourceInformation)); + variables.add( + _makeVariableInitializer( + _handler, + js_ast.number(_rethrowLabel), + bodySourceInformation, + ), + ); + variables.add( + _makeVariableInitializer( + _errorStack, + js_ast.ArrayInitializer(const []), + bodySourceInformation, + ), + ); } if (_analysis.hasFinally || (_isAsyncStar && _analysis.hasYield)) { - variables.add(_makeVariableInitializer( - _next, js_ast.ArrayInitializer([]), bodySourceInformation)); + variables.add( + _makeVariableInitializer( + _next, + js_ast.ArrayInitializer([]), + bodySourceInformation, + ), + ); } - variables.addAll(_localVariables.map((js_ast.VariableBinding declaration) { - return js_ast.VariableInitialization(declaration, null); - })); - variables.addAll([ - for (final scope in _scopeCollector.scopeMapping.values) - if (scope.hasDeclarations) - js_ast.VariableInitialization( - scope.scopeObject, _makeEmptyScopeObject()) - ].reversed); - var variableDeclarationLists = - js_ast.VariableDeclarationList('let', variables); + variables.addAll( + _localVariables.map((js_ast.VariableBinding declaration) { + return js_ast.VariableInitialization(declaration, null); + }), + ); + variables.addAll( + [ + for (final scope in _scopeCollector.scopeMapping.values) + if (scope.hasDeclarations) + js_ast.VariableInitialization( + scope.scopeObject, + _makeEmptyScopeObject(), + ), + ].reversed, + ); + var variableDeclarationLists = js_ast.VariableDeclarationList( + 'let', + variables, + ); // Names are already safe when added. - return _finishFunction(node.params, rewrittenBody, variableDeclarationLists, - exitSourceInformation, bodySourceInformation); + return _finishFunction( + node.params, + rewrittenBody, + variableDeclarationLists, + exitSourceInformation, + bodySourceInformation, + ); } js_ast.Expression _visitFunctionExpression(js_ast.FunctionExpression node) { @@ -796,7 +869,9 @@ // console.log(capturedAsyncScope.foo); // })(asyncScope); return js_ast.Call( - js_ast.ArrowFun(capturedScopeVariableList, node), scopeVariableList); + js_ast.ArrowFun(capturedScopeVariableList, node), + scopeVariableList, + ); } @override @@ -812,10 +887,13 @@ @override js_ast.Expression visitAccess(js_ast.PropertyAccess node) { return withExpression2( - node.receiver, - node.selector, - (receiver, selector) => js_ast.PropertyAccess(receiver, selector) - .withSourceInformation(node.sourceInformation)); + node.receiver, + node.selector, + (receiver, selector) => js_ast.PropertyAccess( + receiver, + selector, + ).withSourceInformation(node.sourceInformation), + ); } @override @@ -833,8 +911,11 @@ @override js_ast.Expression visitAssignment(js_ast.Assignment node) { if (!_shouldTransform(node)) { - return js_ast.Assignment.compound(visitExpression(node.leftHandSide), - node.op, visitExpression(node.value)); + return js_ast.Assignment.compound( + visitExpression(node.leftHandSide), + node.op, + visitExpression(node.value), + ); } var leftHandSide = node.leftHandSide; if (leftHandSide is js_ast.Identifier) { @@ -843,24 +924,31 @@ // use [js_ast.Assignment.compound] for all cases. // Visit the [js_ast.Identifier] to ensure renaming is done correctly. return js_ast.Assignment.compound( - visitExpression(leftHandSide), node.op, value); + visitExpression(leftHandSide), + node.op, + value, + ); }, store: false); } else if (leftHandSide is js_ast.PropertyAccess) { return withExpressions( - [leftHandSide.receiver, leftHandSide.selector, node.value], - (evaluated) { - return js_ast.Assignment.compound( + [leftHandSide.receiver, leftHandSide.selector, node.value], + (evaluated) { + return js_ast.Assignment.compound( js_ast.PropertyAccess(evaluated[0], evaluated[1]), node.op, - evaluated[2]); - }); + evaluated[2], + ); + }, + ); } else { throw 'Unexpected assignment left hand side $leftHandSide'; } } js_ast.Statement awaitStatement( - js_ast.Expression value, Object? sourceInformation); + js_ast.Expression value, + Object? sourceInformation, + ); /// An await is translated to an [awaitStatement]. /// @@ -899,18 +987,22 @@ ? js_ast.Block.empty() : js_ast.js.statement('# = #;', [_result, left]); if (node.op == '&&') { - _addStatement(js_ast.js.statement('if (#) #; else #', [ - left, - _gotoAndBreak(thenLabel, node.sourceInformation), - assignLeft - ])); + _addStatement( + js_ast.js.statement('if (#) #; else #', [ + left, + _gotoAndBreak(thenLabel, node.sourceInformation), + assignLeft, + ]), + ); } else { assert(node.op == '||'); - _addStatement(js_ast.js.statement('if (#) #; else #', [ - left, - assignLeft, - _gotoAndBreak(thenLabel, node.sourceInformation) - ])); + _addStatement( + js_ast.js.statement('if (#) #; else #', [ + left, + assignLeft, + _gotoAndBreak(thenLabel, node.sourceInformation), + ]), + ); } }, store: true); _addGoto(joinLabel, node.sourceInformation); @@ -924,8 +1016,11 @@ return _result; } - return withExpression2(node.left, node.right, - (left, right) => js_ast.Binary(node.op, left, right)); + return withExpression2( + node.left, + node.right, + (left, right) => js_ast.Binary(node.op, left, right), + ); } @override @@ -949,13 +1044,21 @@ @override js_ast.Expression visitCall(js_ast.Call node) { var storeTarget = node.arguments.any(_shouldTransform); - return withCallTargetExpression(node.target, (target) { - return withExpressions(node.arguments, - (List<js_ast.Expression> arguments) { - return js_ast.Call(target, arguments) - .withSourceInformation(node.sourceInformation); - }); - }, store: storeTarget, isCall: true); + return withCallTargetExpression( + node.target, + (target) { + return withExpressions(node.arguments, ( + List<js_ast.Expression> arguments, + ) { + return js_ast.Call( + target, + arguments, + ).withSourceInformation(node.sourceInformation); + }); + }, + store: storeTarget, + isCall: true, + ); } @override @@ -976,22 +1079,26 @@ @override js_ast.Expression visitConditional(js_ast.Conditional node) { if (!_shouldTransform(node.then) && !_shouldTransform(node.otherwise)) { - return js_ast.js('# ? # : #', [ - visitExpression(node.condition), - visitExpression(node.then), - visitExpression(node.otherwise) - ]).withSourceInformation(node.sourceInformation); + return js_ast + .js('# ? # : #', [ + visitExpression(node.condition), + visitExpression(node.then), + visitExpression(node.otherwise), + ]) + .withSourceInformation(node.sourceInformation); } var thenLabel = _newLabel('then'); var joinLabel = _newLabel('join'); var elseLabel = _newLabel('else'); _withExpression(node.condition, (js_ast.Expression condition) { - _addStatement(js_ast.js.statement('# = # ? # : #;', [ - _goto, - condition, - js_ast.number(thenLabel), - js_ast.number(elseLabel) - ])); + _addStatement( + js_ast.js.statement('# = # ? # : #;', [ + _goto, + condition, + js_ast.number(thenLabel), + js_ast.number(elseLabel), + ]), + ); }, store: false); _addBreak(node.sourceInformation); _beginLabel(thenLabel); @@ -1025,11 +1132,13 @@ void _addBreak(Object? sourceInformation) { if (insideUntranslatedBreakable) { hasJumpThoughOuterLabel = true; - _addStatement(js_ast.Break(_outerLabelName) - .withSourceInformation(sourceInformation)); + _addStatement( + js_ast.Break(_outerLabelName).withSourceInformation(sourceInformation), + ); } else { _addStatement( - js_ast.Break(null).withSourceInformation(sourceInformation)); + js_ast.Break(null).withSourceInformation(sourceInformation), + ); } } @@ -1040,7 +1149,10 @@ /// /// See also [_rewriteFunction]. void _translateJump( - js_ast.Node? target, int? targetLabel, Object? sourceInformation) { + js_ast.Node? target, + int? targetLabel, + Object? sourceInformation, + ) { // Compute a stack of all the 'finally' nodes that must be visited before // the jump. // The bottom of the stack is the label where the jump goes to. @@ -1060,9 +1172,15 @@ var firstTarget = jumpStack.removeLast(); if (jumpStack.isNotEmpty) { var jsJumpStack = js_ast.ArrayInitializer( - jumpStack.map((int label) => js_ast.number(label)).toList()); - _addStatement(js_ast.ExpressionStatement(js_ast.js('# = #', - [_next, jsJumpStack]).withSourceInformation(sourceInformation))); + jumpStack.map((int label) => js_ast.number(label)).toList(), + ); + _addStatement( + js_ast.ExpressionStatement( + js_ast + .js('# = #', [_next, jsJumpStack]) + .withSourceInformation(sourceInformation), + ), + ); } _addGoto(firstTarget, sourceInformation); } @@ -1075,8 +1193,12 @@ if (!_shouldTransform(node)) { var oldInsideUntranslatedBreakable = insideUntranslatedBreakable; insideUntranslatedBreakable = true; - _addStatement(js_ast.js.statement('do {#} while (#)', - [_translateToStatement(node.body), visitExpression(node.condition)])); + _addStatement( + js_ast.js.statement('do {#} while (#)', [ + _translateToStatement(node.body), + visitExpression(node.condition), + ]), + ); insideUntranslatedBreakable = oldInsideUntranslatedBreakable; return; } @@ -1096,8 +1218,12 @@ _beginLabel(continueLabel); _withExpression(node.condition, (js_ast.Expression condition) { - _addStatement(js_ast.js.statement('if (#) #', - [condition, _gotoAndBreak(startLabel, node.sourceInformation)])); + _addStatement( + js_ast.js.statement('if (#) #', [ + condition, + _gotoAndBreak(startLabel, node.sourceInformation), + ]), + ); }, store: false); _beginLabel(afterLabel); } @@ -1126,19 +1252,31 @@ final newInitializationList = <js_ast.VariableInitialization>[]; for (final initialization in init.declarations) { final value = initialization.value; - newInitializationList.add(js_ast.VariableInitialization( + newInitializationList.add( + js_ast.VariableInitialization( initialization.declaration, - value != null ? visitExpression(value) : null)); + value != null ? visitExpression(value) : null, + ), + ); } - newInit = - js_ast.VariableDeclarationList(init.keyword, newInitializationList); + newInit = js_ast.VariableDeclarationList( + init.keyword, + newInitializationList, + ); } else { newInit = init != null ? visitExpression(init) : null; } - withNullableExpressions([node.condition, node.update], - (List<js_ast.Expression?> transformed) { - _addStatement(js_ast.For(newInit, transformed[0], transformed[1], - _translateToStatement(node.body))); + withNullableExpressions([node.condition, node.update], ( + List<js_ast.Expression?> transformed, + ) { + _addStatement( + js_ast.For( + newInit, + transformed[0], + transformed[1], + _translateToStatement(node.body), + ), + ); }); insideUntranslatedBreakable = oldInsideUntranslated; return; @@ -1151,8 +1289,9 @@ var startLabel = _newLabel('for condition'); // If there is no update, continuing the loop is the same as going to the // start. - var continueLabel = - (node.update == null) ? startLabel : _newLabel('for update'); + var continueLabel = (node.update == null) + ? startLabel + : _newLabel('for update'); _continueLabels[node] = continueLabel; var afterLabel = _newLabel('after for'); _breakLabels[node] = afterLabel; @@ -1163,8 +1302,12 @@ _addStatement(js_ast.Comment('trivial condition')); } else { _withExpression(condition, (js_ast.Expression condition) { - _addStatement(js_ast.If.noElse(js_ast.Prefix('!', condition), - _gotoAndBreak(afterLabel, node.sourceInformation))); + _addStatement( + js_ast.If.noElse( + js_ast.Prefix('!', condition), + _gotoAndBreak(afterLabel, node.sourceInformation), + ), + ); }, store: false); } _jumpTargets.add(node); @@ -1190,7 +1333,8 @@ final name = visitExpression(node.name); _hoistIfNecessary(name); _addExpressionStatement( - js_ast.Assignment(visitExpression(name), function)); + js_ast.Assignment(visitExpression(name), function), + ); }, store: false); } @@ -1231,10 +1375,16 @@ : _newLabel('else'); _withExpression(node.condition, (js_ast.Expression condition) { - _addExpressionStatement(js_ast.Assignment( + _addExpressionStatement( + js_ast.Assignment( _goto, js_ast.Conditional( - condition, js_ast.number(thenLabel), js_ast.number(elseLabel)))); + condition, + js_ast.number(thenLabel), + js_ast.number(elseLabel), + ), + ), + ); }, store: false); _addBreak(node.sourceInformation); _beginLabel(thenLabel); @@ -1275,8 +1425,9 @@ @override void visitLabeledStatement(js_ast.LabeledStatement node) { if (!_shouldTransform(node)) { - _addStatement(js_ast.LabeledStatement( - node.label, _translateToStatement(node.body))); + _addStatement( + js_ast.LabeledStatement(node.label, _translateToStatement(node.body)), + ); return; } // `continue label` is really continuing the nested loop. @@ -1319,29 +1470,39 @@ @override js_ast.Expression visitNew(js_ast.New node) { var storeTarget = node.arguments.any(_shouldTransform); - return withCallTargetExpression(node.target, (target) { - return withExpressions(node.arguments, - (List<js_ast.Expression> arguments) { - return js_ast.New(target, arguments); - }); - }, store: storeTarget, isCall: false); + return withCallTargetExpression( + node.target, + (target) { + return withExpressions(node.arguments, ( + List<js_ast.Expression> arguments, + ) { + return js_ast.New(target, arguments); + }); + }, + store: storeTarget, + isCall: false, + ); } @override js_ast.Expression visitObjectInitializer(js_ast.ObjectInitializer node) { return withExpressions( - node.properties - .map((js_ast.Property property) => property.value) - .toList(), (List<js_ast.Expression> values) { - var properties = List<js_ast.Property>.generate(values.length, (int i) { - if (node.properties[i] is js_ast.Method) { - return js_ast.Method( - node.properties[i].name, values[i] as js_ast.Fun); - } - return js_ast.Property(node.properties[i].name, values[i]); - }); - return js_ast.ObjectInitializer(properties); - }); + node.properties + .map((js_ast.Property property) => property.value) + .toList(), + (List<js_ast.Expression> values) { + var properties = List<js_ast.Property>.generate(values.length, (int i) { + if (node.properties[i] is js_ast.Method) { + return js_ast.Method( + node.properties[i].name, + values[i] as js_ast.Fun, + ); + } + return js_ast.Property(node.properties[i].name, values[i]); + }); + return js_ast.ObjectInitializer(properties); + }, + ); } @override @@ -1351,19 +1512,25 @@ if (argument is js_ast.Identifier) { return js_ast.Postfix(node.op, visitExpression(argument)); } else if (argument is js_ast.PropertyAccess) { - return withExpression2(argument.receiver, argument.selector, - (receiver, selector) { + return withExpression2(argument.receiver, argument.selector, ( + receiver, + selector, + ) { return js_ast.Postfix( - node.op, js_ast.PropertyAccess(receiver, selector)); + node.op, + js_ast.PropertyAccess(receiver, selector), + ); }); } else { throw 'Unexpected postfix ${node.op} ' 'operator argument ${node.argument}'; } } - return _withExpression(node.argument, - (js_ast.Expression argument) => js_ast.Postfix(node.op, argument), - store: false); + return _withExpression( + node.argument, + (js_ast.Expression argument) => js_ast.Postfix(node.op, argument), + store: false, + ); } @override @@ -1373,19 +1540,25 @@ if (argument is js_ast.Identifier) { return js_ast.Prefix(node.op, visitExpression(argument)); } else if (argument is js_ast.PropertyAccess) { - return withExpression2(argument.receiver, argument.selector, - (receiver, selector) { + return withExpression2(argument.receiver, argument.selector, ( + receiver, + selector, + ) { return js_ast.Prefix( - node.op, js_ast.PropertyAccess(receiver, selector)); + node.op, + js_ast.PropertyAccess(receiver, selector), + ); }); } else { throw 'Unexpected prefix ${node.op} operator ' 'argument ${node.argument}'; } } - return _withExpression(node.argument, - (js_ast.Expression argument) => js_ast.Prefix(node.op, argument), - store: false); + return _withExpression( + node.argument, + (js_ast.Expression argument) => js_ast.Prefix(node.op, argument), + store: false, + ); } @override @@ -1394,18 +1567,21 @@ @override js_ast.Property visitProperty(js_ast.Property node) { assert(node.runtimeType == js_ast.Property); - return _withExpression(node.value, - (js_ast.Expression value) => js_ast.Property(node.name, value), - store: false); + return _withExpression( + node.value, + (js_ast.Expression value) => js_ast.Property(node.name, value), + store: false, + ); } @override js_ast.Method visitMethod(js_ast.Method node) { return _withExpression( - node.function, - (js_ast.Expression value) => - js_ast.Method(node.name, value as js_ast.Fun), - store: false); + node.function, + (js_ast.Expression value) => + js_ast.Method(node.name, value as js_ast.Fun), + store: false, + ); } @override @@ -1425,9 +1601,11 @@ _visitExpressionIgnoreResult(expression); } else { _withExpression(expression, (js_ast.Expression value) { - _addStatement(js_ast.js - .statement('# = #;', [_returnValue, value]).withSourceInformation( - node.sourceInformation)); + _addStatement( + js_ast.js + .statement('# = #;', [_returnValue, value]) + .withSourceInformation(node.sourceInformation), + ); }, store: false); } } @@ -1444,10 +1622,13 @@ var cases = node.cases.map((js_ast.SwitchClause clause) { if (clause is js_ast.Case) { return js_ast.Case( - clause.expression, translateToBlock(clause.body)); + clause.expression, + translateToBlock(clause.body), + ); } else { return js_ast.Default( - translateToBlock((clause as js_ast.Default).body)); + translateToBlock((clause as js_ast.Default).body), + ); } }).toList(); _addStatement(js_ast.Switch(key, cases)); @@ -1462,8 +1643,10 @@ _beginLabel(before); var labels = List<int>.filled(node.cases.length, -1); - var anyCaseExpressionTransformed = node.cases.any((js_ast.SwitchClause x) => - x is js_ast.Case && _shouldTransform(x.expression)); + var anyCaseExpressionTransformed = node.cases.any( + (js_ast.SwitchClause x) => + x is js_ast.Case && _shouldTransform(x.expression), + ); if (anyCaseExpressionTransformed) { int? defaultIndex; // Null means no default was found. // If there is an await in one of the keys, a chain of ifs has to be used. @@ -1480,9 +1663,12 @@ } else if (clause is js_ast.Case) { labels[i] = _newLabel('case'); _withExpression(clause.expression, (expression) { - _addStatement(js_ast.If.noElse( + _addStatement( + js_ast.If.noElse( js_ast.Binary('===', key, expression), - _gotoAndBreak(labels[i], clause.sourceInformation))); + _gotoAndBreak(labels[i], clause.sourceInformation), + ), + ); }, store: false); } i++; @@ -1501,12 +1687,17 @@ for (var clause in node.cases) { if (clause is js_ast.Case) { labels[i] = _newLabel('case'); - clauses.add(js_ast.Case(visitExpression(clause.expression), - _gotoAndBreak(labels[i], clause.sourceInformation))); + clauses.add( + js_ast.Case( + visitExpression(clause.expression), + _gotoAndBreak(labels[i], clause.sourceInformation), + ), + ); } else if (clause is js_ast.Default) { labels[i] = _newLabel('default'); - clauses.add(js_ast.Default( - _gotoAndBreak(labels[i], clause.sourceInformation))); + clauses.add( + js_ast.Default(_gotoAndBreak(labels[i], clause.sourceInformation)), + ); hasDefault = true; } else { throw StateError('Unknown clause type $clause'); @@ -1514,8 +1705,9 @@ i++; } if (!hasDefault) { - clauses - .add(js_ast.Default(_gotoAndBreak(after, node.sourceInformation))); + clauses.add( + js_ast.Default(_gotoAndBreak(after, node.sourceInformation)), + ); } _withExpression(node.key, (js_ast.Expression key) { _addStatement(js_ast.Switch(key, clauses)); @@ -1539,8 +1731,9 @@ @override void visitThrow(js_ast.Throw node) { _withExpression(node.expression, (js_ast.Expression expression) { - _addStatement(js_ast.Throw(expression) - .withSourceInformation(node.sourceInformation)); + _addStatement( + js_ast.Throw(expression).withSourceInformation(node.sourceInformation), + ); }, store: false); } @@ -1580,12 +1773,16 @@ js_ast.Catch? translatedCatchPart; if (catchPart != null) { translatedCatchPart = js_ast.Catch( - catchPart.declaration, translateToBlock(catchPart.body)); + catchPart.declaration, + translateToBlock(catchPart.body), + ); } - var translatedFinallyPart = - (finallyPart == null) ? null : translateToBlock(finallyPart); + var translatedFinallyPart = (finallyPart == null) + ? null + : translateToBlock(finallyPart); _addStatement( - js_ast.Try(body, translatedCatchPart, translatedFinallyPart)); + js_ast.Try(body, translatedCatchPart, translatedFinallyPart), + ); return; } @@ -1617,8 +1814,12 @@ _addGoto(afterFinallyLabel, node.sourceInformation); } else { // The handler is reset as the first thing in the finally block. - _addStatement(js_ast.js - .statement('#.push(#);', [_next, js_ast.number(afterFinallyLabel)])); + _addStatement( + js_ast.js.statement('#.push(#);', [ + _next, + js_ast.number(afterFinallyLabel), + ]), + ); _addGoto(finallyLabel, node.sourceInformation); } @@ -1635,13 +1836,18 @@ var errorName = visitExpression(catchPart.declaration); _hoistIfNecessary(errorName); _addStatement( - js_ast.js.statement('# = #.pop();', [errorName, _errorStack])); + js_ast.js.statement('# = #.pop();', [errorName, _errorStack]), + ); _visitStatement(catchPart.body); if (finallyPart != null) { // The error has been caught, so after the finally, continue after the // try. - _addStatement(js_ast.js.statement( - '#.push(#);', [_next, js_ast.number(afterFinallyLabel)])); + _addStatement( + js_ast.js.statement('#.push(#);', [ + _next, + js_ast.number(afterFinallyLabel), + ]), + ); _addGoto(finallyLabel, node.sourceInformation); } else { _addGoto(afterFinallyLabel, node.sourceInformation); @@ -1660,10 +1866,14 @@ if (enclosingFinallies.isNotEmpty) { // [enclosingFinallies] can be empty if there is no surrounding finally // blocks. Then [nextLabel] will be [rethrowLabel]. - _addStatement(js_ast.js.statement('# = #;', [ - _next, - js_ast.ArrayInitializer(enclosingFinallies.map(js_ast.number).toList()) - ])); + _addStatement( + js_ast.js.statement('# = #;', [ + _next, + js_ast.ArrayInitializer( + enclosingFinallies.map(js_ast.number).toList(), + ), + ]), + ); } if (finallyPart == null) { // The finally-block belonging to [node] will be visited because of @@ -1686,16 +1896,18 @@ @override js_ast.Expression visitVariableDeclarationList( - js_ast.VariableDeclarationList node) { + js_ast.VariableDeclarationList node, + ) { for (final initialization in node.declarations) { var declaration = visitExpression(initialization.declaration); _hoistIfNecessary(declaration); if (initialization.value != null) { _withExpression(initialization.value!, (js_ast.Expression value) { _addExpressionStatement( - js_ast.Assignment(declaration, value) - ..sourceInformation = initialization.sourceInformation, - node.sourceInformation); + js_ast.Assignment(declaration, value) + ..sourceInformation = initialization.sourceInformation, + node.sourceInformation, + ); }, store: false); } } @@ -1718,8 +1930,12 @@ var oldInsideUntranslated = insideUntranslatedBreakable; insideUntranslatedBreakable = true; _withExpression(node.condition, (js_ast.Expression condition) { - _addStatement(js_ast.While(condition, _translateToStatement(node.body)) - .withSourceInformation(node.sourceInformation)); + _addStatement( + js_ast.While( + condition, + _translateToStatement(node.body), + ).withSourceInformation(node.sourceInformation), + ); }, store: false); insideUntranslatedBreakable = oldInsideUntranslated; return; @@ -1734,9 +1950,12 @@ // If the condition is `true`, a test is not needed. if (!(condition is js_ast.LiteralBool && condition.value == true)) { _withExpression(node.condition, (js_ast.Expression condition) { - _addStatement(js_ast.If.noElse(js_ast.Prefix('!', condition), - _gotoAndBreak(afterLabel, node.sourceInformation)) - .withSourceInformation(node.sourceInformation)); + _addStatement( + js_ast.If.noElse( + js_ast.Prefix('!', condition), + _gotoAndBreak(afterLabel, node.sourceInformation), + ).withSourceInformation(node.sourceInformation), + ); }, store: false); } _jumpTargets.add(node); @@ -1746,8 +1965,11 @@ _beginLabel(afterLabel); } - void addYield(js_ast.DartYield node, js_ast.Expression expression, - Object? sourceInformation); + void addYield( + js_ast.DartYield node, + js_ast.Expression expression, + Object? sourceInformation, + ); @override void visitDartYield(js_ast.DartYield node) { @@ -1767,30 +1989,39 @@ if (!_shouldTransform(node)) { var oldInsideUntranslated = insideUntranslatedBreakable; insideUntranslatedBreakable = true; - _addStatement(js_ast.ForOf(node.leftHandSide, - visitExpression(node.iterable), _translateToStatement(node.body))); + _addStatement( + js_ast.ForOf( + node.leftHandSide, + visitExpression(node.iterable), + _translateToStatement(node.body), + ), + ); insideUntranslatedBreakable = oldInsideUntranslated; return; } _visitExpressionIgnoreResult(node.leftHandSide); final loopVar = visitExpression( - (node.leftHandSide as js_ast.VariableDeclarationList) - .declarations - .first - .declaration); + (node.leftHandSide as js_ast.VariableDeclarationList) + .declarations + .first + .declaration, + ); final valueWrapperVar = ScopedId('t\$wrappedValue'); final iteratorVar = ScopedId('t\$iterator'); _localVariables.add(valueWrapperVar); _localVariables.add(iteratorVar); - // Get the iterator object for the iterable expresion. + // Get the iterator object for the iterable expression. _withExpression(node.iterable, (js_ast.Expression iterable) { - _addExpressionStatement(js_ast.Assignment( + _addExpressionStatement( + js_ast.Assignment( iteratorVar, js_ast.js('#[Symbol.iterator]()', [iterable]) - ..sourceInformation = node.iterable.sourceInformation)); + ..sourceInformation = node.iterable.sourceInformation, + ), + ); }, store: false); var continueLabel = _newLabel('for-of iterator update'); @@ -1806,12 +2037,18 @@ // 3b) If yes: jump to after the loop body. _beginLabel(continueLabel); _resetScopeIfNecessary(node); - _addExpressionStatement(js_ast.Assignment( - valueWrapperVar, js_ast.js('#.next()', [iteratorVar]))); - _addStatement(js_ast.If.noElse(js_ast.js('#.done', [valueWrapperVar]), - _gotoAndBreak(afterLabel, node.sourceInformation))); _addExpressionStatement( - js_ast.Assignment(loopVar, js_ast.js('#.value', [valueWrapperVar]))); + js_ast.Assignment(valueWrapperVar, js_ast.js('#.next()', [iteratorVar])), + ); + _addStatement( + js_ast.If.noElse( + js_ast.js('#.done', [valueWrapperVar]), + _gotoAndBreak(afterLabel, node.sourceInformation), + ), + ); + _addExpressionStatement( + js_ast.Assignment(loopVar, js_ast.js('#.value', [valueWrapperVar])), + ); _jumpTargets.add(node); _visitStatement(node.body); _jumpTargets.removeLast(); @@ -1822,8 +2059,8 @@ @override js_ast.ArrayBindingPattern visitArrayBindingPattern( - js_ast.ArrayBindingPattern node) => - node; + js_ast.ArrayBindingPattern node, + ) => node; @override Never visitClassDeclaration(js_ast.ClassDeclaration node) => @@ -1834,18 +2071,18 @@ @override js_ast.CommentExpression visitCommentExpression( - js_ast.CommentExpression node) => - node; + js_ast.CommentExpression node, + ) => node; @override js_ast.DebuggerStatement visitDebuggerStatement( - js_ast.DebuggerStatement node) => - node; + js_ast.DebuggerStatement node, + ) => node; @override js_ast.DestructuredVariable visitDestructuredVariable( - js_ast.DestructuredVariable node) => - node; + js_ast.DestructuredVariable node, + ) => node; @override Never visitExportClause(js_ast.ExportClause node) => _unreachable(node); @@ -1860,29 +2097,29 @@ @override js_ast.InterpolatedIdentifier visitInterpolatedIdentifier( - js_ast.InterpolatedIdentifier node) => - node; + js_ast.InterpolatedIdentifier node, + ) => node; @override js_ast.InterpolatedMethod visitInterpolatedMethod( - js_ast.InterpolatedMethod node) => - node; + js_ast.InterpolatedMethod node, + ) => node; @override Never visitNameSpecifier(js_ast.NameSpecifier node) => _unreachable(node); @override js_ast.ObjectBindingPattern visitObjectBindingPattern( - js_ast.ObjectBindingPattern node) => - node; + js_ast.ObjectBindingPattern node, + ) => node; @override js_ast.RestParameter visitRestParameter(js_ast.RestParameter node) => node; @override js_ast.SimpleBindingPattern visitSimpleBindingPattern( - js_ast.SimpleBindingPattern node) => - node; + js_ast.SimpleBindingPattern node, + ) => node; @override js_ast.Spread visitSpread(js_ast.Spread node) => node; @@ -1901,11 +2138,14 @@ } js_ast.VariableInitialization _makeVariableInitializer( - js_ast.Identifier variable, - js_ast.Expression? initValue, - Object? sourceInformation) { - return js_ast.VariableInitialization(variable, initValue) - .withSourceInformation(sourceInformation) + js_ast.Identifier variable, + js_ast.Expression? initValue, + Object? sourceInformation, +) { + return js_ast.VariableInitialization( + variable, + initValue, + ).withSourceInformation(sourceInformation) as js_ast.VariableInitialization; } @@ -1958,19 +2198,23 @@ final js_ast.Expression wrapBody; - AsyncRewriter( - {required this.asyncStart, - required this.asyncAwait, - required this.asyncReturn, - required this.asyncRethrow, - required this.completerFactory, - required this.completerFactoryTypeArguments, - required this.wrapBody, - required super.bodyName}); + AsyncRewriter({ + required this.asyncStart, + required this.asyncAwait, + required this.asyncReturn, + required this.asyncRethrow, + required this.completerFactory, + required this.completerFactoryTypeArguments, + required this.wrapBody, + required super.bodyName, + }); @override - void addYield(js_ast.DartYield node, js_ast.Expression expression, - Object? sourceInformation) { + void addYield( + js_ast.DartYield node, + js_ast.Expression expression, + Object? sourceInformation, + ) { throw StateError('Yield in non-generating async function'); } @@ -1978,14 +2222,16 @@ void addErrorExit(Object? sourceInformation) { if (!_hasHandlerLabels) return; // rethrow handled in method boilerplate. _beginLabel(_rethrowLabel); - var thenHelperCall = js_ast.js( - '#thenHelper(#errorStack.at(-1), #completer)', { - 'thenHelper': asyncRethrow, - 'errorStack': _errorStack, - 'completer': completer - }).withSourceInformation(sourceInformation); + var thenHelperCall = js_ast + .js('#thenHelper(#errorStack.at(-1), #completer)', { + 'thenHelper': asyncRethrow, + 'errorStack': _errorStack, + 'completer': completer, + }) + .withSourceInformation(sourceInformation); _addStatement( - js_ast.Return(thenHelperCall).withSourceInformation(sourceInformation)); + js_ast.Return(thenHelperCall).withSourceInformation(sourceInformation), + ); } /// Returning from an async method calls [asyncStarHelper] with the result. @@ -1999,70 +2245,85 @@ _addStatement(js_ast.Comment('implicit return')); } - var runtimeHelperCall = - js_ast.js('#runtimeHelper(#returnValue, #completer)', { - 'runtimeHelper': asyncReturn, - 'returnValue': - _analysis.hasExplicitReturns ? _returnValue : js_ast.LiteralNull(), - 'completer': completer - }).withSourceInformation(sourceInformation); - _addStatement(js_ast.Return(runtimeHelperCall) - .withSourceInformation(sourceInformation)); + var runtimeHelperCall = js_ast + .js('#runtimeHelper(#returnValue, #completer)', { + 'runtimeHelper': asyncReturn, + 'returnValue': _analysis.hasExplicitReturns + ? _returnValue + : js_ast.LiteralNull(), + 'completer': completer, + }) + .withSourceInformation(sourceInformation); + _addStatement( + js_ast.Return(runtimeHelperCall).withSourceInformation(sourceInformation), + ); } @override Iterable<js_ast.VariableInitialization> variableInitializations( - Object? sourceInformation) { + Object? sourceInformation, + ) { var variables = <js_ast.VariableInitialization>[]; - variables.add(_makeVariableInitializer( + variables.add( + _makeVariableInitializer( completer, - js_ast.js('#(#)', [ - completerFactory, - completerFactoryTypeArguments - ]).withSourceInformation(sourceInformation), - sourceInformation)); + js_ast + .js('#(#)', [completerFactory, completerFactoryTypeArguments]) + .withSourceInformation(sourceInformation), + sourceInformation, + ), + ); if (_analysis.hasExplicitReturns) { - variables - .add(_makeVariableInitializer(_returnValue, null, sourceInformation)); + variables.add( + _makeVariableInitializer(_returnValue, null, sourceInformation), + ); } return variables; } @override js_ast.Statement awaitStatement( - js_ast.Expression value, Object? sourceInformation) { - var asyncHelperCall = - js_ast.js('#asyncHelper(#value, #bodyName, #completer)', { - 'asyncHelper': asyncAwait, - 'value': value, - 'bodyName': bodyName, - 'completer': completer, - }).withSourceInformation(sourceInformation); - return js_ast.Return(asyncHelperCall) + js_ast.Expression value, + Object? sourceInformation, + ) { + var asyncHelperCall = js_ast + .js('#asyncHelper(#value, #bodyName, #completer)', { + 'asyncHelper': asyncAwait, + 'value': value, + 'bodyName': bodyName, + 'completer': completer, + }) .withSourceInformation(sourceInformation); + return js_ast.Return( + asyncHelperCall, + ).withSourceInformation(sourceInformation); } @override js_ast.Fun _finishFunction( - List<js_ast.Parameter> parameters, - js_ast.Statement rewrittenBody, - js_ast.VariableDeclarationList variableDeclarationLists, - Object? functionSourceInformation, - Object? bodySourceInformation) { + List<js_ast.Parameter> parameters, + js_ast.Statement rewrittenBody, + js_ast.VariableDeclarationList variableDeclarationLists, + Object? functionSourceInformation, + Object? bodySourceInformation, + ) { js_ast.Statement errorCheck; if (_hasHandlerLabels) { - errorCheck = js_ast.js.statement(''' + errorCheck = js_ast.js.statement( + ''' if (#errorCode === #ERROR) { #errorStack.push(#result); #goto = #handler; - }''', { - 'errorCode': _errorCode, - 'ERROR': js_ast.number(status_codes.ERROR), - 'errorStack': _errorStack, - 'result': _result, - 'goto': _goto, - 'handler': _handler, - }); + }''', + { + 'errorCode': _errorCode, + 'ERROR': js_ast.number(status_codes.ERROR), + 'errorStack': _errorStack, + 'result': _result, + 'goto': _goto, + 'handler': _handler, + }, + ); } else { var asyncRethrowCall = js_ast.js('#asyncRethrow(#result, #completer)', { 'result': _result, @@ -2070,49 +2331,67 @@ 'completer': completer, }); var returnAsyncRethrow = js_ast.Return(asyncRethrowCall); - errorCheck = js_ast.js.statement(''' + errorCheck = js_ast.js.statement( + ''' if (#errorCode === #ERROR) #returnAsyncRethrow; - ''', { - 'errorCode': _errorCode, - 'ERROR': js_ast.number(status_codes.ERROR), - 'returnAsyncRethrow': returnAsyncRethrow, - }); + ''', + { + 'errorCode': _errorCode, + 'ERROR': js_ast.number(status_codes.ERROR), + 'returnAsyncRethrow': returnAsyncRethrow, + }, + ); } // Use an arrow function so that we can access 'this' from the outer scope. - var innerFunction = js_ast.js(''' + var innerFunction = js_ast + .js( + ''' (#errorCode, #result) => { #errorCheck; #rewrittenBody; - }''', { - 'errorCode': _errorCode, - 'result': _result, - 'errorCheck': errorCheck, - 'rewrittenBody': rewrittenBody, - }).withSourceInformation(bodySourceInformation); - var asyncStartCall = js_ast.js('#asyncStart(#bodyName, #completer)', { - 'asyncStart': asyncStart, - 'bodyName': bodyName, - 'completer': completer, - }).withSourceInformation(bodySourceInformation); + }''', + { + 'errorCode': _errorCode, + 'result': _result, + 'errorCheck': errorCheck, + 'rewrittenBody': rewrittenBody, + }, + ) + .withSourceInformation(bodySourceInformation); + var asyncStartCall = js_ast + .js('#asyncStart(#bodyName, #completer)', { + 'asyncStart': asyncStart, + 'bodyName': bodyName, + 'completer': completer, + }) + .withSourceInformation(bodySourceInformation); var returnAsyncStart = js_ast.Return(asyncStartCall); - var wrapBodyCall = js_ast.js('#wrapBody(#innerFunction)', { - 'wrapBody': wrapBody, - 'innerFunction': innerFunction, - }).withSourceInformation(bodySourceInformation); - return (js_ast.js(''' + var wrapBodyCall = js_ast + .js('#wrapBody(#innerFunction)', { + 'wrapBody': wrapBody, + 'innerFunction': innerFunction, + }) + .withSourceInformation(bodySourceInformation); + return (js_ast + .js( + ''' function (#parameters) { #variableDeclarationLists; var #bodyName = #wrapBodyCall; #returnAsyncStart; - }''', { - 'parameters': parameters, - 'variableDeclarationLists': variableDeclarationLists, - 'bodyName': bodyName, - 'wrapBodyCall': wrapBodyCall, - 'returnAsyncStart': returnAsyncStart, - }).withSourceInformation(functionSourceInformation)) as js_ast.Fun; + }''', + { + 'parameters': parameters, + 'variableDeclarationLists': variableDeclarationLists, + 'bodyName': bodyName, + 'wrapBodyCall': wrapBodyCall, + 'returnAsyncStart': returnAsyncStart, + }, + ) + .withSourceInformation(functionSourceInformation)) + as js_ast.Fun; } } @@ -2134,24 +2413,28 @@ /// Property of the iterator that contains the current value. final js_ast.Expression iteratorCurrentValueProperty; - /// Property of the iterator that contains the uncaught exeception. + /// Property of the iterator that contains the uncaught exception. final js_ast.Expression iteratorDatumProperty; /// Property of the iterator that is bound to the `_yieldStar` method. final js_ast.Expression yieldStarSelector; - SyncStarRewriter( - {required this.makeSyncStarIterable, - required this.syncStarIterableTypeArgument, - required this.iteratorCurrentValueProperty, - required this.iteratorDatumProperty, - required this.yieldStarSelector, - required super.bodyName}); + SyncStarRewriter({ + required this.makeSyncStarIterable, + required this.syncStarIterableTypeArgument, + required this.iteratorCurrentValueProperty, + required this.iteratorDatumProperty, + required this.yieldStarSelector, + required super.bodyName, + }); /// Translates a yield/yield* in an sync*. @override - void addYield(js_ast.DartYield node, js_ast.Expression expression, - Object? sourceInformation) { + void addYield( + js_ast.DartYield node, + js_ast.Expression expression, + Object? sourceInformation, + ) { if (node.hasStar) { // ``yield* expression` is translated to: // @@ -2159,10 +2442,13 @@ // // The `_yieldStar` method updates the state of the Iterator to 'enter' // the expression and returns the SYNC_STAR_YIELD_STAR status code. - _addStatement(js_ast.Return(js_ast.Call( - js_ast.PropertyAccess(iterator, yieldStarSelector), - [expression]).withSourceInformation(sourceInformation)) - .withSourceInformation(sourceInformation)); + _addStatement( + js_ast.Return( + js_ast.Call(js_ast.PropertyAccess(iterator, yieldStarSelector), [ + expression, + ]).withSourceInformation(sourceInformation), + ).withSourceInformation(sourceInformation), + ); } else { // `yield expression` is translated to: // @@ -2171,21 +2457,29 @@ // This sets the `_current` field of the Iterator and returns the // SYNC_STAR_YIELD status code. final store = js_ast.Assignment( - js_ast.PropertyAccess(iterator, iteratorCurrentValueProperty), - expression); - _addStatement(js_ast.Return(js_ast.Binary( - ',', store, js_ast.number(status_codes.SYNC_STAR_YIELD))) - .withSourceInformation(sourceInformation)); + js_ast.PropertyAccess(iterator, iteratorCurrentValueProperty), + expression, + ); + _addStatement( + js_ast.Return( + js_ast.Binary( + ',', + store, + js_ast.number(status_codes.SYNC_STAR_YIELD), + ), + ).withSourceInformation(sourceInformation), + ); } } @override js_ast.Fun _finishFunction( - List<js_ast.Parameter> parameters, - js_ast.Statement rewrittenBody, - js_ast.VariableDeclarationList variableDeclarationLists, - Object? functionSourceInformation, - Object? bodySourceInformation) { + List<js_ast.Parameter> parameters, + js_ast.Statement rewrittenBody, + js_ast.VariableDeclarationList variableDeclarationLists, + Object? functionSourceInformation, + Object? bodySourceInformation, + ) { // Each iterator invocation on the iterable should work on its own copy of // the parameters. Since parameter initialization code at the start of the // function may reference the original parameter names, we create an alias @@ -2201,18 +2495,24 @@ ScopedId() => ScopedId.from(parameter), js_ast.DestructuredVariable() when parameter.name is ScopedId => ScopedId.from(parameter.name as ScopedId), - _ => js_ast.Identifier(name) + _ => js_ast.Identifier(name), }; - innerDeclarationsList - .add(js_ast.VariableInitialization(parameterRef, renamedIdentifier)); - outerDeclarationsList - .add(js_ast.VariableInitialization(renamedIdentifier, parameterRef)); + innerDeclarationsList.add( + js_ast.VariableInitialization(parameterRef, renamedIdentifier), + ); + outerDeclarationsList.add( + js_ast.VariableInitialization(renamedIdentifier, parameterRef), + ); } - var outerDeclarations = - js_ast.VariableDeclarationList('let', outerDeclarationsList); - var innerDeclarations = - js_ast.VariableDeclarationList('let', innerDeclarationsList); + var outerDeclarations = js_ast.VariableDeclarationList( + 'let', + outerDeclarationsList, + ); + var innerDeclarations = js_ast.VariableDeclarationList( + 'let', + innerDeclarationsList, + ); var pushError = js_ast.js('#errorStack.push(#result)', { 'result': _result, @@ -2222,61 +2522,76 @@ 'goto': _goto, 'handler': _handler, }); - var checkErrorCode = js_ast.js.statement(''' + var checkErrorCode = js_ast.js.statement( + ''' if (#errorCode === #ERROR) { #pushError; #setGoto; - }''', { - 'errorCode': _errorCode, - 'ERROR': js_ast.number(status_codes.ERROR), - 'pushError': pushError, - 'setGoto': setGoto, - }); + }''', + { + 'errorCode': _errorCode, + 'ERROR': js_ast.number(status_codes.ERROR), + 'pushError': pushError, + 'setGoto': setGoto, + }, + ); // Use an arrow function so that we can access 'this' from the outer scope. - var innerInnerFunction = js_ast.js(''' + var innerInnerFunction = js_ast.js( + ''' (#iterator, #errorCode, #result) => { #checkErrorCode; #helperBody; - }''', { - 'helperBody': rewrittenBody, - 'errorCode': _errorCode, - 'iterator': iterator, - 'result': _result, - 'checkErrorCode': checkErrorCode, - }); + }''', + { + 'helperBody': rewrittenBody, + 'errorCode': _errorCode, + 'iterator': iterator, + 'result': _result, + 'checkErrorCode': checkErrorCode, + }, + ); var returnInnerInnerFunction = js_ast.Return(innerInnerFunction); // Use an arrow function so that we can access 'this' from the outer scope. - var innerInnerFunctionInvocation = js_ast.js(''' + var innerInnerFunctionInvocation = js_ast.js( + ''' #makeSyncStarIterable(#iterableType, () => { if (#hasParameters) { #innerDeclarations; } #varDecl; #returnInnerInnerFunction; - })''', { - 'hasParameters': parameters.isNotEmpty, - 'innerDeclarations': innerDeclarations, - 'varDecl': variableDeclarationLists, - 'returnInnerInnerFunction': returnInnerInnerFunction, - 'makeSyncStarIterable': makeSyncStarIterable, - 'iterableType': syncStarIterableTypeArgument, - }); + })''', + { + 'hasParameters': parameters.isNotEmpty, + 'innerDeclarations': innerDeclarations, + 'varDecl': variableDeclarationLists, + 'returnInnerInnerFunction': returnInnerInnerFunction, + 'makeSyncStarIterable': makeSyncStarIterable, + 'iterableType': syncStarIterableTypeArgument, + }, + ); var returnInnerFunction = js_ast.Return(innerInnerFunctionInvocation); // Add the copied parameter declarations outside the inner function in case // one is a type parameter that gets passed to the inner function. - return (js_ast.js(''' + return (js_ast + .js( + ''' function (#parameters) { if (#hasParameters) { #outerDeclarations; } #returnInnerFunction; } - ''', { - 'hasParameters': parameters.isNotEmpty, - 'outerDeclarations': outerDeclarations, - 'parameters': parameters, - 'returnInnerFunction': returnInnerFunction, - }).withSourceInformation(functionSourceInformation)) as js_ast.Fun; + ''', + { + 'hasParameters': parameters.isNotEmpty, + 'outerDeclarations': outerDeclarations, + 'parameters': parameters, + 'returnInnerFunction': returnInnerFunction, + }, + ) + .withSourceInformation(functionSourceInformation)) + as js_ast.Fun; } @override @@ -2290,11 +2605,18 @@ // This stashes the exception on the Iterator and returns the // SYNC_STAR_UNCAUGHT_EXCEPTION status code. final store = js_ast.Assignment( - js_ast.PropertyAccess(iterator, iteratorDatumProperty), - js_ast.js('#.at(-1)', [_errorStack])); - _addStatement(js_ast.Return(js_ast.Binary(',', store, - js_ast.number(status_codes.SYNC_STAR_UNCAUGHT_EXCEPTION))) - .withSourceInformation(sourceInformation)); + js_ast.PropertyAccess(iterator, iteratorDatumProperty), + js_ast.js('#.at(-1)', [_errorStack]), + ); + _addStatement( + js_ast.Return( + js_ast.Binary( + ',', + store, + js_ast.number(status_codes.SYNC_STAR_UNCAUGHT_EXCEPTION), + ), + ).withSourceInformation(sourceInformation), + ); } /// Returning from a sync* function returns the SYNC_STAR_DONE status code. @@ -2305,20 +2627,26 @@ } else { _addStatement(js_ast.Comment('implicit return')); } - _addStatement(js_ast.Return(js_ast.number(status_codes.SYNC_STAR_DONE)) - .withSourceInformation(sourceInformation)); + _addStatement( + js_ast.Return( + js_ast.number(status_codes.SYNC_STAR_DONE), + ).withSourceInformation(sourceInformation), + ); } @override Iterable<js_ast.VariableInitialization> variableInitializations( - Object? sourceInformation) { + Object? sourceInformation, + ) { var variables = <js_ast.VariableInitialization>[]; return variables; } @override js_ast.Statement awaitStatement( - js_ast.Expression value, Object? sourceInformation) { + js_ast.Expression value, + Object? sourceInformation, + ) { throw StateError('Sync* functions cannot contain await statements.'); } } @@ -2329,8 +2657,9 @@ /// The stack of labels of finally blocks to assign to [_next] if the /// async* [StreamSubscription] was canceled during a yield. - late final js_ast.Identifier nextWhenCanceled = - ScopedId('t\$nextWhenCanceled'); + late final js_ast.Identifier nextWhenCanceled = ScopedId( + 't\$nextWhenCanceled', + ); /// The StreamController that controls an async* function. late final js_ast.Identifier controller = ScopedId('t\$controller'); @@ -2374,15 +2703,16 @@ final js_ast.Expression wrapBody; - AsyncStarRewriter( - {required this.asyncStarHelper, - required this.streamOfController, - required this.newController, - required this.newControllerTypeArguments, - required this.yieldExpression, - required this.yieldStarExpression, - required this.wrapBody, - required super.bodyName}); + AsyncStarRewriter({ + required this.asyncStarHelper, + required this.streamOfController, + required this.newController, + required this.newControllerTypeArguments, + required this.yieldExpression, + required this.yieldStarExpression, + required this.wrapBody, + required super.bodyName, + }); /// Translates a yield/yield* in an async* function. /// @@ -2393,51 +2723,66 @@ /// Also [nextWhenCanceled] is set up to contain the finally blocks that /// must be run in case the stream was canceled. @override - void addYield(js_ast.DartYield node, js_ast.Expression expression, - Object? sourceInformation) { + void addYield( + js_ast.DartYield node, + js_ast.Expression expression, + Object? sourceInformation, + ) { // Find all the finally blocks that should be performed if the stream is // canceled during the yield. var enclosingFinallyLabels = <int>[ // At the bottom of the stack is the return label. _exitLabel, for (final node in _jumpTargets) - if (_finallyLabels[node] != null) _finallyLabels[node]! + if (_finallyLabels[node] != null) _finallyLabels[node]!, ]; - _addStatement(js_ast.js.statement('# = #;', [ - nextWhenCanceled, - js_ast.ArrayInitializer( - enclosingFinallyLabels.map(js_ast.number).toList()) - ]).withSourceInformation(sourceInformation)); - var yieldExpressionCall = js_ast.js('#yieldExpression(#expression)', { - 'yieldExpression': node.hasStar ? yieldStarExpression : yieldExpression, - 'expression': expression, - }).withSourceInformation(sourceInformation); + _addStatement( + js_ast.js + .statement('# = #;', [ + nextWhenCanceled, + js_ast.ArrayInitializer( + enclosingFinallyLabels.map(js_ast.number).toList(), + ), + ]) + .withSourceInformation(sourceInformation), + ); + var yieldExpressionCall = js_ast + .js('#yieldExpression(#expression)', { + 'yieldExpression': node.hasStar + ? yieldStarExpression + : yieldExpression, + 'expression': expression, + }) + .withSourceInformation(sourceInformation); var asyncStarHelperCall = js_ast .js('#asyncStarHelper(#yieldExpressionCall, #bodyName, #controller)', { - 'asyncStarHelper': asyncStarHelper, - 'yieldExpressionCall': yieldExpressionCall, - 'bodyName': bodyName, - 'controller': controller, - }).withSourceInformation(sourceInformation); - _addStatement(js_ast.Return(asyncStarHelperCall) - .withSourceInformation(sourceInformation)); + 'asyncStarHelper': asyncStarHelper, + 'yieldExpressionCall': yieldExpressionCall, + 'bodyName': bodyName, + 'controller': controller, + }) + .withSourceInformation(sourceInformation); + _addStatement( + js_ast.Return( + asyncStarHelperCall, + ).withSourceInformation(sourceInformation), + ); } @override js_ast.Fun _finishFunction( - List<js_ast.Parameter> parameters, - js_ast.Statement rewrittenBody, - js_ast.VariableDeclarationList variableDeclarationLists, - Object? functionSourceInformation, - Object? bodySourceInformation) { + List<js_ast.Parameter> parameters, + js_ast.Statement rewrittenBody, + js_ast.VariableDeclarationList variableDeclarationLists, + Object? functionSourceInformation, + Object? bodySourceInformation, + ) { var updateNext = js_ast.js('#next = #nextWhenCanceled', { 'next': _next, 'nextWhenCanceled': nextWhenCanceled, }); - var callPop = js_ast.js('#next.pop()', { - 'next': _next, - }); + var callPop = js_ast.js('#next.pop()', {'next': _next}); var gotoCancelled = js_ast.js('#goto = #callPop', { 'goto': _goto, 'callPop': callPop, @@ -2451,7 +2796,8 @@ 'handler': _handler, }); var breakStatement = js_ast.Break(null); - var switchCase = js_ast.js.statement(''' + var switchCase = js_ast.js.statement( + ''' switch (#errorCode) { case #STREAM_WAS_CANCELED: #updateNext; @@ -2460,88 +2806,110 @@ case #ERROR: #pushError; #gotoError; - }''', { - 'errorCode': _errorCode, - 'STREAM_WAS_CANCELED': js_ast.number(status_codes.STREAM_WAS_CANCELED), - 'updateNext': updateNext, - 'gotoCancelled': gotoCancelled, - 'break': breakStatement, - 'ERROR': js_ast.number(status_codes.ERROR), - 'pushError': pushError, - 'gotoError': gotoError, - }); - var ifError = js_ast.js.statement(''' + }''', + { + 'errorCode': _errorCode, + 'STREAM_WAS_CANCELED': js_ast.number(status_codes.STREAM_WAS_CANCELED), + 'updateNext': updateNext, + 'gotoCancelled': gotoCancelled, + 'break': breakStatement, + 'ERROR': js_ast.number(status_codes.ERROR), + 'pushError': pushError, + 'gotoError': gotoError, + }, + ); + var ifError = js_ast.js.statement( + ''' if (#errorCode === #ERROR) { #pushError; #gotoError; - }''', { - 'errorCode': _errorCode, - 'ERROR': js_ast.number(status_codes.ERROR), - 'pushError': pushError, - 'gotoError': gotoError, - }); - var ifHasYield = js_ast.js.statement(''' + }''', + { + 'errorCode': _errorCode, + 'ERROR': js_ast.number(status_codes.ERROR), + 'pushError': pushError, + 'gotoError': gotoError, + }, + ); + var ifHasYield = js_ast.js.statement( + ''' if (#hasYield) { #switchCase } else { #ifError; } - ''', { - 'hasYield': _analysis.hasYield, - 'switchCase': switchCase, - 'ifError': ifError, - }); + ''', + { + 'hasYield': _analysis.hasYield, + 'switchCase': switchCase, + 'ifError': ifError, + }, + ); // Use an arrow function so that we can access 'this' from the outer scope. - var innerFunction = js_ast.js(''' + var innerFunction = js_ast + .js( + ''' (#errorCode, #result) => { #ifHasYield; #rewrittenBody; - }''', { - 'errorCode': _errorCode, - 'result': _result, - 'ifHasYield': ifHasYield, - 'rewrittenBody': rewrittenBody, - }).withSourceInformation(functionSourceInformation); - var wrapBodyCall = js_ast.js('#wrapBody(#innerFunction)', { - 'wrapBody': wrapBody, - 'innerFunction': innerFunction, - }).withSourceInformation(bodySourceInformation); - var declareBodyName = - js_ast.js.statement('var #bodyName = #wrapBodyCall;', { - 'bodyName': bodyName, - 'wrapBodyCall': wrapBodyCall, - }); + }''', + { + 'errorCode': _errorCode, + 'result': _result, + 'ifHasYield': ifHasYield, + 'rewrittenBody': rewrittenBody, + }, + ) + .withSourceInformation(functionSourceInformation); + var wrapBodyCall = js_ast + .js('#wrapBody(#innerFunction)', { + 'wrapBody': wrapBody, + 'innerFunction': innerFunction, + }) + .withSourceInformation(bodySourceInformation); + var declareBodyName = js_ast.js.statement( + 'var #bodyName = #wrapBodyCall;', + {'bodyName': bodyName, 'wrapBodyCall': wrapBodyCall}, + ); var streamOfControllerCall = js_ast.js('#streamOfController(#controller)', { 'streamOfController': streamOfController, 'controller': controller, }); var returnStreamOfControllerCall = js_ast.Return(streamOfControllerCall); - return (js_ast.js(''' + return (js_ast + .js( + ''' function (#parameters) { #declareBodyName; #variableDeclarationLists; #returnStreamOfControllerCall; - }''', { - 'parameters': parameters, - 'declareBodyName': declareBodyName, - 'variableDeclarationLists': variableDeclarationLists, - 'returnStreamOfControllerCall': returnStreamOfControllerCall, - }).withSourceInformation(functionSourceInformation)) as js_ast.Fun; + }''', + { + 'parameters': parameters, + 'declareBodyName': declareBodyName, + 'variableDeclarationLists': variableDeclarationLists, + 'returnStreamOfControllerCall': returnStreamOfControllerCall, + }, + ) + .withSourceInformation(functionSourceInformation)) + as js_ast.Fun; } @override void addErrorExit(Object? sourceInformation) { _hasHandlerLabels = true; _beginLabel(_rethrowLabel); - var asyncHelperCall = - js_ast.js('#asyncHelper(#errorStack.at(-1), #errorCode, #controller)', { - 'asyncHelper': asyncStarHelper, - 'errorCode': js_ast.number(status_codes.ERROR), - 'errorStack': _errorStack, - 'controller': controller - }).withSourceInformation(sourceInformation); - _addStatement(js_ast.Return(asyncHelperCall) - .withSourceInformation(sourceInformation)); + var asyncHelperCall = js_ast + .js('#asyncHelper(#errorStack.at(-1), #errorCode, #controller)', { + 'asyncHelper': asyncStarHelper, + 'errorCode': js_ast.number(status_codes.ERROR), + 'errorStack': _errorStack, + 'controller': controller, + }) + .withSourceInformation(sourceInformation); + _addStatement( + js_ast.Return(asyncHelperCall).withSourceInformation(sourceInformation), + ); } /// Returning from an async* function calls the [streamHelper] with an @@ -2550,47 +2918,60 @@ void addSuccessExit(Object? sourceInformation) { _beginLabel(_exitLabel); - var streamHelperCall = - js_ast.js('#streamHelper(null, #successCode, #controller)', { - 'streamHelper': asyncStarHelper, - 'successCode': js_ast.number(status_codes.SUCCESS), - 'controller': controller - }).withSourceInformation(sourceInformation); - _addStatement(js_ast.Return(streamHelperCall) - .withSourceInformation(sourceInformation)); + var streamHelperCall = js_ast + .js('#streamHelper(null, #successCode, #controller)', { + 'streamHelper': asyncStarHelper, + 'successCode': js_ast.number(status_codes.SUCCESS), + 'controller': controller, + }) + .withSourceInformation(sourceInformation); + _addStatement( + js_ast.Return(streamHelperCall).withSourceInformation(sourceInformation), + ); } @override Iterable<js_ast.VariableInitialization> variableInitializations( - Object? sourceInformation) { + Object? sourceInformation, + ) { var variables = <js_ast.VariableInitialization>[]; - variables.add(_makeVariableInitializer( + variables.add( + _makeVariableInitializer( controller, - js_ast.js('#(#, #)', [ - newController, - newControllerTypeArguments, - bodyName - ]).withSourceInformation(sourceInformation), - sourceInformation)); + js_ast + .js('#(#, #)', [ + newController, + newControllerTypeArguments, + bodyName, + ]) + .withSourceInformation(sourceInformation), + sourceInformation, + ), + ); if (_analysis.hasYield) { variables.add( - _makeVariableInitializer(nextWhenCanceled, null, sourceInformation)); + _makeVariableInitializer(nextWhenCanceled, null, sourceInformation), + ); } return variables; } @override js_ast.Statement awaitStatement( - js_ast.Expression value, Object? sourceInformation) { - var asyncHelperCall = - js_ast.js('#asyncHelper(#value, #bodyName, #controller)', { - 'asyncHelper': asyncStarHelper, - 'value': value, - 'bodyName': bodyName, - 'controller': controller - }).withSourceInformation(sourceInformation); - return js_ast.Return(asyncHelperCall) + js_ast.Expression value, + Object? sourceInformation, + ) { + var asyncHelperCall = js_ast + .js('#asyncHelper(#value, #bodyName, #controller)', { + 'asyncHelper': asyncStarHelper, + 'value': value, + 'bodyName': bodyName, + 'controller': controller, + }) .withSourceInformation(sourceInformation); + return js_ast.Return( + asyncHelperCall, + ).withSourceInformation(sourceInformation); } } @@ -2686,8 +3067,9 @@ @override bool visitBreak(js_ast.Break node) { if (node.targetLabel != null) { - targets[node] = - labelledStatements.lastWhere((js_ast.LabeledStatement statement) { + targets[node] = labelledStatements.lastWhere(( + js_ast.LabeledStatement statement, + ) { return statement.label == node.targetLabel; }); } else { @@ -2736,11 +3118,13 @@ bool visitContinue(js_ast.Continue node) { if (node.targetLabel != null) { var targetLabel = labelledStatements.lastWhere( - (js_ast.LabeledStatement stm) => stm.label == node.targetLabel); + (js_ast.LabeledStatement stm) => stm.label == node.targetLabel, + ); targets[node] = targetLabel.body; } else { - targets[node] = loopsAndSwitches - .lastWhere((js_ast.Node node) => node is! js_ast.Switch); + targets[node] = loopsAndSwitches.lastWhere( + (js_ast.Node node) => node is! js_ast.Switch, + ); } assert(() { var target = targets[node]; @@ -2966,8 +3350,9 @@ if (node.finallyPart != null) hasFinally = true; var body = visit(node.body); var catchPart = (node.catchPart == null) ? false : visit(node.catchPart!); - var finallyPart = - (node.finallyPart == null) ? false : visit(node.finallyPart!); + var finallyPart = (node.finallyPart == null) + ? false + : visit(node.finallyPart!); return body || catchPart || finallyPart; } @@ -3135,7 +3520,7 @@ final Map<String, _ScopeInfo> _nameDeclarations; _ScopeInfo([Map<String, _ScopeInfo>? nameDeclarations]) - : _nameDeclarations = {...?nameDeclarations}; + : _nameDeclarations = {...?nameDeclarations}; _ScopeInfo childScope() { return _ScopeInfo(_nameDeclarations); @@ -3143,8 +3528,10 @@ void declare(js_ast.Identifier node, bool isUntrackedDeclaration) { final key = node.name; - assert(_nameDeclarations[key] != this, - 'Name "$node" already declared in scope.'); + assert( + _nameDeclarations[key] != this, + 'Name "$node" already declared in scope.', + ); if (isUntrackedDeclaration) { _nameDeclarations.remove(key); } else { @@ -3192,7 +3579,7 @@ final captureVariable = closureInfo.usedScopes[declaringScope]; return captureVariable != null ? (js_ast.PropertyAccess.field(captureVariable, node.name) - ..sourceInformation = node.sourceInformation) + ..sourceInformation = node.sourceInformation) : node; } }
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart index 4655804..5245cd5 100644 --- a/pkg/dev_compiler/lib/src/js_ast/builder.dart +++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -409,7 +409,10 @@ CommentExpression(text, expression); Call propertyCall( - Expression receiver, String fieldName, List<Expression> arguments) { + Expression receiver, + String fieldName, + List<Expression> arguments, + ) { return Call(PropertyAccess.field(receiver, fieldName), arguments); } } @@ -419,7 +422,10 @@ ArrayInitializer numArray(Iterable<int> list) => js.numArray(list); ArrayInitializer stringArray(Iterable<String> list) => js.stringArray(list); Call propertyCall( - Expression receiver, String fieldName, List<Expression> arguments) { + Expression receiver, + String fieldName, + List<Expression> arguments, +) { return js.propertyCall(receiver, fieldName, arguments); } @@ -589,7 +595,7 @@ ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, // abcdefgh ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, // ijklmnop ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, ALPHA, // qrstuvwx - ALPHA, ALPHA, LBRACE, SYMBOL, RBRACE, SYMBOL + ALPHA, ALPHA, LBRACE, SYMBOL, RBRACE, SYMBOL, ]; // yz{|}~ // This must be a >= the highest precedence number handled by parseBinary. @@ -646,7 +652,7 @@ 'typeof', 'void', 'delete', - 'await' + 'await', }; static final ARROW_TOKEN = '=>'; @@ -659,7 +665,7 @@ 'in', 'instanceof', 'await', - 'extends' + 'extends', }; static int category(int code) { @@ -1113,8 +1119,9 @@ expectCategory(COMMA); } } - receiver = - constructor ? New(receiver, arguments) : Call(receiver, arguments); + receiver = constructor + ? New(receiver, arguments) + : Call(receiver, arguments); constructor = false; } else if (!constructor && acceptCategory(LSQUARE)) { Expression inBraces = parseExpression(); @@ -1240,8 +1247,10 @@ return Assignment(lhs, rhs); } else { // Handle +=, -=, etc. - String operator = - assignmentOperator.substring(0, assignmentOperator.length - 1); + String operator = assignmentOperator.substring( + 0, + assignmentOperator.length - 1, + ); return Assignment.compound(lhs, operator, rhs); } } @@ -1258,8 +1267,10 @@ } /// Parse a variable declaration list, with `var` or `let` [keyword]. - VariableDeclarationList parseVariableDeclarationList(String keyword, - [String? firstIdentifier]) { + VariableDeclarationList parseVariableDeclarationList( + String keyword, [ + String? firstIdentifier, + ]) { var initialization = <VariableInitialization>[]; do { @@ -1325,8 +1336,13 @@ if (acceptString('=')) { defaultValue = parseExpression(); } - variables.add(DestructuredVariable( - name: name, structure: structure, defaultValue: defaultValue)); + variables.add( + DestructuredVariable( + name: name, + structure: structure, + defaultValue: defaultValue, + ), + ); } while (acceptCategory(COMMA)); expectCategory(RSQUARE); @@ -1345,8 +1361,13 @@ } else if (acceptString('=')) { defaultValue = parseExpression(); } - variables.add(DestructuredVariable( - name: name, structure: structure, defaultValue: defaultValue)); + variables.add( + DestructuredVariable( + name: name, + structure: structure, + defaultValue: defaultValue, + ), + ); } while (acceptCategory(COMMA)); expectCategory(RBRACE); @@ -1469,8 +1490,9 @@ // statement. if (expression is InterpolatedExpression) { assert(identical(interpolatedValues.last, expression)); - InterpolatedStatement statement = - InterpolatedStatement(expression.nameOrPosition); + InterpolatedStatement statement = InterpolatedStatement( + expression.nameOrPosition, + ); interpolatedValues[interpolatedValues.length - 1] = statement; return statement; } @@ -1564,14 +1586,20 @@ Expression objectExpression = parseExpression(); expectCategory(RPAREN); Statement body = parseStatement(); - return ForIn(_createVariableDeclarationList(keyword, identifier), - objectExpression, body); + return ForIn( + _createVariableDeclarationList(keyword, identifier), + objectExpression, + body, + ); } else if (acceptString('of')) { Expression iterableExpression = parseAssignment(); expectCategory(RPAREN); Statement body = parseStatement(); - return ForOf(_createVariableDeclarationList(keyword, identifier), - iterableExpression, body); + return ForOf( + _createVariableDeclarationList(keyword, identifier), + iterableExpression, + body, + ); } var declarations = parseVariableDeclarationList(keyword, identifier); expectCategory(SEMICOLON); @@ -1584,9 +1612,12 @@ } static VariableDeclarationList _createVariableDeclarationList( - String keyword, String identifier) { - return VariableDeclarationList( - keyword, [VariableInitialization(Identifier(identifier), null)]); + String keyword, + String identifier, + ) { + return VariableDeclarationList(keyword, [ + VariableInitialization(Identifier(identifier), null), + ]); } Statement parseFunctionDeclaration() { @@ -1731,8 +1762,13 @@ return Property(name, value); } else { var fun = parseFun(); - return Method(name, fun, - isGetter: isGetter, isSetter: isSetter, isStatic: isStatic); + return Method( + name, + fun, + isGetter: isGetter, + isSetter: isSetter, + isStatic: isStatic, + ); } }
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart index f6f7287..e877ebc 100644 --- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart +++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -323,7 +323,9 @@ /// Returns a node equivalent to [this], but with new source position and end /// source position. T _withSourceInformation<T extends Node>( - Object? sourceInformation, T Function() cloneFunc) { + Object? sourceInformation, + T Function() cloneFunc, + ) { if (sourceInformation == this.sourceInformation) { return this as T; } @@ -362,14 +364,8 @@ class LibraryBundle extends Program { final List<Program> libraries; - LibraryBundle( - this.libraries, { - super.name, - super.scriptTag, - super.header, - }) : super( - const [], - ); + LibraryBundle(this.libraries, {super.name, super.scriptTag, super.header}) + : super(const []); @override T accept<T>(NodeVisitor<T> visitor) => visitor.visitProgram(this); @@ -382,8 +378,12 @@ } @override - LibraryBundle _clone() => LibraryBundle(libraries, - name: name, scriptTag: scriptTag, header: header); + LibraryBundle _clone() => LibraryBundle( + libraries, + name: name, + scriptTag: scriptTag, + header: header, + ); } // TODO(nshahan): Rename to convey that this is a single Dart library after @@ -411,8 +411,13 @@ // is removed. final Identifier? librarySelfVar; - Program(this.body, - {this.scriptTag, this.name, this.header = const [], this.librarySelfVar}); + Program( + this.body, { + this.scriptTag, + this.name, + this.header = const [], + this.librarySelfVar, + }); @override T accept<T>(NodeVisitor<T> visitor) => visitor.visitProgram(this); @@ -480,9 +485,7 @@ Block(this.statements, {this.isScope = false}); - Block.empty() - : statements = <Statement>[], - isScope = false; + Block.empty() : statements = <Statement>[], isScope = false; @override bool get alwaysReturns => @@ -973,8 +976,9 @@ // TODO(jmesserly): make this work for more cases? Statement toVariableDeclaration(VariableBinding name) => - VariableDeclarationList('let', [VariableInitialization(name, this)]) - .toStatement(); + VariableDeclarationList('let', [ + VariableInitialization(name, this), + ]).toStatement(); @override Expression _clone(); @@ -1119,8 +1123,12 @@ final BindingPattern? structure; final Expression? defaultValue; - DestructuredVariable( - {required this.name, this.property, this.structure, this.defaultValue}); + DestructuredVariable({ + required this.name, + this.property, + this.structure, + this.defaultValue, + }); @override bool shadows(Set<String> names) { @@ -1144,10 +1152,11 @@ String get parameterName => name.name; @override DestructuredVariable _clone() => DestructuredVariable( - name: name, - property: property, - structure: structure, - defaultValue: defaultValue); + name: name, + property: property, + structure: structure, + defaultValue: defaultValue, + ); } abstract class BindingPattern extends Expression implements VariableBinding { @@ -1567,8 +1576,12 @@ @override final AsyncModifier asyncModifier; - Fun(this.params, this.body, - {this.isGenerator = false, this.asyncModifier = AsyncModifier.sync}); + Fun( + this.params, + this.body, { + this.isGenerator = false, + this.asyncModifier = AsyncModifier.sync, + }); @override T accept<T>(NodeVisitor<T> visitor) => visitor.visitFun(this); @@ -1627,10 +1640,11 @@ asyncStar(isAsync: true, isYielding: true, description: 'async*'), syncStar(isAsync: false, isYielding: true, description: 'sync*'); - const AsyncModifier( - {required this.isAsync, - required this.isYielding, - required this.description}); + const AsyncModifier({ + required this.isAsync, + required this.isYielding, + required this.description, + }); final bool isAsync; final bool isYielding; @@ -1645,9 +1659,9 @@ PropertyAccess(this.receiver, this.selector); PropertyAccess.field(this.receiver, String fieldName) - : selector = LiteralString('"$fieldName"'); + : selector = LiteralString('"$fieldName"'); PropertyAccess.indexed(this.receiver, int index) - : selector = LiteralNumber('$index'); + : selector = LiteralNumber('$index'); @override T accept<T>(NodeVisitor<T> visitor) => visitor.visitAccess(this); @@ -1778,7 +1792,7 @@ /// Constructs a new object-initializer containing the given [properties]. ObjectInitializer(this.properties, {bool multiline = false}) - : _multiline = multiline; + : _multiline = multiline; @override T accept<T>(NodeVisitor<T> visitor) => visitor.visitObjectInitializer(this); @@ -1811,8 +1825,12 @@ final bool isStatic; final bool isClassProperty; - Property(this.name, this.value, - {this.isStatic = false, this.isClassProperty = false}); + Property( + this.name, + this.value, { + this.isStatic = false, + this.isClassProperty = false, + }); @override T accept<T>(NodeVisitor<T> visitor) => visitor.visitProperty(this); @@ -1824,8 +1842,12 @@ } @override - Property _clone() => Property(name, value, - isStatic: isStatic, isClassProperty: isClassProperty); + Property _clone() => Property( + name, + value, + isStatic: isStatic, + isClassProperty: isClassProperty, + ); } // TODO(jmesserly): parser does not support this yet. @@ -1974,8 +1996,13 @@ @override final bool isClassProperty = false; - Method(this.name, this.function, - {this.isGetter = false, this.isSetter = false, this.isStatic = false}) { + Method( + this.name, + this.function, { + this.isGetter = false, + this.isSetter = false, + this.isStatic = false, + }) { assert(!isGetter || function.params.isEmpty); assert(!isSetter || function.params.length == 1); assert(!isGetter && !isSetter || !function.isGenerator); @@ -1994,8 +2021,13 @@ } @override - Method _clone() => Method(name, function, - isGetter: isGetter, isSetter: isSetter, isStatic: isStatic); + Method _clone() => Method( + name, + function, + isGetter: isGetter, + isSetter: isSetter, + isStatic: isStatic, + ); } /// Tag class for all interpolated positions. @@ -2275,8 +2307,11 @@ final LiteralString from; - ImportDeclaration( - {this.defaultBinding, this.namedImports, required this.from}); + ImportDeclaration({ + this.defaultBinding, + this.namedImports, + required this.from, + }); /// The `import "name.js"` form of import. ImportDeclaration.all(LiteralString module) : this(from: module); @@ -2305,7 +2340,10 @@ @override ImportDeclaration _clone() => ImportDeclaration( - defaultBinding: defaultBinding, namedImports: namedImports, from: from); + defaultBinding: defaultBinding, + namedImports: namedImports, + from: from, + ); } class ExportDeclaration extends ModuleItem { @@ -2320,11 +2358,13 @@ final bool isDefault; ExportDeclaration(this.exported, {this.isDefault = false}) { - assert(exported is ClassDeclaration || - exported is FunctionDeclaration || - isDefault - ? exported is Expression - : exported is VariableDeclarationList || exported is ExportClause); + assert( + exported is ClassDeclaration || + exported is FunctionDeclaration || + isDefault + ? exported is Expression + : exported is VariableDeclarationList || exported is ExportClause, + ); } /// Gets the list of names exported by this export declaration, or `null` @@ -2368,7 +2408,7 @@ /// The `export * from 'name.js'` form. ExportClause.star(LiteralString from) - : this([NameSpecifier.star()], from: from); + : this([NameSpecifier.star()], from: from); /// True if this is an `export *`. bool get exportStar => exports.length == 1 && exports[0].isStar; @@ -2447,31 +2487,46 @@ } N transformIfUnchanged1<N extends Node, T extends Node>( - N node, T childNode, N Function(T newChildNode) clone) { + N node, + T childNode, + N Function(T newChildNode) clone, + ) { final newChildNode = visit<T>(childNode); final hasNoChange = isUnchanged(childNode, newChildNode); return hasNoChange ? node : clone(newChildNode); } N transformIfUnchanged2<N extends Node, T extends Node, U extends Node>( - N node, - T childNode1, - U childNode2, - N Function(T newChildNode1, U newChildNode2) clone) { + N node, + T childNode1, + U childNode2, + N Function(T newChildNode1, U newChildNode2) clone, + ) { final newChildNode1 = visit<T>(childNode1); final newChildNode2 = visit<U>(childNode2); - final hasNoChange = isUnchanged(childNode1, newChildNode1) && + final hasNoChange = + isUnchanged(childNode1, newChildNode1) && isUnchanged(childNode2, newChildNode2); return hasNoChange ? node : clone(newChildNode1, newChildNode2); } - N transformIfUnchanged3<N extends Node, T extends Node, U extends Node, - V extends Node>(N node, T childNode1, U childNode2, V childNode3, - N Function(T newChildNode1, U newChildNode2, V newChildNode3) clone) { + N transformIfUnchanged3< + N extends Node, + T extends Node, + U extends Node, + V extends Node + >( + N node, + T childNode1, + U childNode2, + V childNode3, + N Function(T newChildNode1, U newChildNode2, V newChildNode3) clone, + ) { final newChildNode1 = visit<T>(childNode1); final newChildNode2 = visit<U>(childNode2); final newChildNode3 = visit<V>(childNode3); - final hasNoChange = isUnchanged(childNode1, newChildNode1) && + final hasNoChange = + isUnchanged(childNode1, newChildNode1) && isUnchanged(childNode2, newChildNode2) && isUnchanged(childNode3, newChildNode3); return hasNoChange @@ -2480,20 +2535,25 @@ } N transformIfUnchangedList<N extends Node, T extends Node>( - N node, List<T> childNodes, N Function(List<T> newChildNodes) clone) { + N node, + List<T> childNodes, + N Function(List<T> newChildNodes) clone, + ) { final newChildNodes = visitList<T>(childNodes); final hasNoChange = isUnchangedList(childNodes, newChildNodes); return hasNoChange ? node : clone(newChildNodes); } N transformIfUnchangedList1<N extends Node, T extends Node, U extends Node>( - N node, - List<T> childNodeList, - U childNode, - N Function(List<T> newChildNodeList, U childNode) clone) { + N node, + List<T> childNodeList, + U childNode, + N Function(List<T> newChildNodeList, U childNode) clone, + ) { final newChildNodeList = visitList<T>(childNodeList); final newChildNode = visit<U>(childNode); - final hasNoChange = isUnchangedList(childNodeList, newChildNodeList) && + final hasNoChange = + isUnchangedList(childNodeList, newChildNodeList) && isUnchanged(childNode, newChildNode); return hasNoChange ? node : clone(newChildNodeList, newChildNode); } @@ -2507,13 +2567,20 @@ @override Node visitAccess(PropertyAccess node) { return transformIfUnchanged2( - node, node.receiver, node.selector, PropertyAccess.new); + node, + node.receiver, + node.selector, + PropertyAccess.new, + ); } @override Node visitArrayBindingPattern(ArrayBindingPattern node) { return transformIfUnchangedList( - node, node.variables, ArrayBindingPattern.new); + node, + node.variables, + ArrayBindingPattern.new, + ); } @override @@ -2524,17 +2591,29 @@ @override Node visitArrowFun(ArrowFun node) { return transformIfUnchangedList1( - node, node.params, node.body, ArrowFun.new); + node, + node.params, + node.body, + ArrowFun.new, + ); } @override Node visitAssignment(Assignment node) { if (node.isCompound) { - return transformIfUnchanged2(node, node.leftHandSide, node.value, - (e1, e2) => Assignment.compound(e1, node.op, e2)); + return transformIfUnchanged2( + node, + node.leftHandSide, + node.value, + (e1, e2) => Assignment.compound(e1, node.op, e2), + ); } return transformIfUnchanged2( - node, node.leftHandSide, node.value, Assignment.new); + node, + node.leftHandSide, + node.value, + Assignment.new, + ); } @override @@ -2545,7 +2624,11 @@ @override Node visitBinary(Binary node) { return transformIfUnchanged2( - node, node.left, node.right, (e1, e2) => Binary(node.op, e1, e2)); + node, + node.left, + node.right, + (e1, e2) => Binary(node.op, e1, e2), + ); } @override @@ -2556,7 +2639,11 @@ @override Node visitCall(Call node) { return transformIfUnchangedList1( - node, node.arguments, node.target, (e1, e2) => Call(e2, e1)); + node, + node.arguments, + node.target, + (e1, e2) => Call(e2, e1), + ); } @override @@ -2590,19 +2677,30 @@ @override Node visitCommentExpression(CommentExpression node) { return transformIfUnchanged1( - node, node.expression, (e) => CommentExpression(node.comment, e)); + node, + node.expression, + (e) => CommentExpression(node.comment, e), + ); } @override Node visitConditional(Conditional node) { return transformIfUnchanged3( - node, node.condition, node.then, node.otherwise, Conditional.new); + node, + node.condition, + node.then, + node.otherwise, + Conditional.new, + ); } @override Node visitDartYield(DartYield node) { return transformIfUnchanged1( - node, node.expression, (e) => DartYield(e, node.hasStar)); + node, + node.expression, + (e) => DartYield(e, node.hasStar), + ); } @override @@ -2624,10 +2722,11 @@ return node; } return DestructuredVariable( - name: name, - property: property, - structure: structure, - defaultValue: defaultValue); + name: name, + property: property, + structure: structure, + defaultValue: defaultValue, + ); } @override @@ -2648,14 +2747,20 @@ @override Node visitExportDeclaration(ExportDeclaration node) { - return transformIfUnchanged1(node, node.exported, - (e) => ExportDeclaration(e, isDefault: node.isDefault)); + return transformIfUnchanged1( + node, + node.exported, + (e) => ExportDeclaration(e, isDefault: node.isDefault), + ); } @override Node visitExpressionStatement(ExpressionStatement node) { return transformIfUnchanged1( - node, node.expression, ExpressionStatement.new); + node, + node.expression, + ExpressionStatement.new, + ); } @override @@ -2676,35 +2781,59 @@ @override Node visitForIn(ForIn node) { return transformIfUnchanged3( - node, node.leftHandSide, node.object, node.body, ForIn.new); + node, + node.leftHandSide, + node.object, + node.body, + ForIn.new, + ); } @override Node visitForOf(ForOf node) { return transformIfUnchanged3( - node, node.leftHandSide, node.iterable, node.body, ForOf.new); + node, + node.leftHandSide, + node.iterable, + node.body, + ForOf.new, + ); } @override Node visitFun(Fun node) { return transformIfUnchangedList1( - node, - node.params, - node.body, - (e1, e2) => Fun(e1, e2, - isGenerator: node.isGenerator, asyncModifier: node.asyncModifier)); + node, + node.params, + node.body, + (e1, e2) => Fun( + e1, + e2, + isGenerator: node.isGenerator, + asyncModifier: node.asyncModifier, + ), + ); } @override Node visitFunctionDeclaration(FunctionDeclaration node) { return transformIfUnchanged2( - node, node.name, node.function, FunctionDeclaration.new); + node, + node.name, + node.function, + FunctionDeclaration.new, + ); } @override Node visitIf(If node) { return transformIfUnchanged3( - node, node.condition, node.then, node.otherwise, If.new); + node, + node.condition, + node.then, + node.otherwise, + If.new, + ); } @override @@ -2718,25 +2847,35 @@ return node; } return ImportDeclaration( - defaultBinding: defaultBinding, namedImports: namedImports, from: from); + defaultBinding: defaultBinding, + namedImports: namedImports, + from: from, + ); } @override Node visitLabeledStatement(LabeledStatement node) { return transformIfUnchanged1( - node, node.body, (e) => LabeledStatement(node.label, e)); + node, + node.body, + (e) => LabeledStatement(node.label, e), + ); } @override Node visitMethod(Method node) { return transformIfUnchanged2( - node, - node.name, - node.function, - (e1, e2) => Method(e1, e2, - isGetter: node.isGetter, - isSetter: node.isSetter, - isStatic: node.isStatic)); + node, + node.name, + node.function, + (e1, e2) => Method( + e1, + e2, + isGetter: node.isGetter, + isSetter: node.isSetter, + isStatic: node.isStatic, + ), + ); } @override @@ -2751,38 +2890,58 @@ @override Node visitNamedFunction(NamedFunction node) { - return transformIfUnchanged2(node, node.name, node.function, - (e1, e2) => NamedFunction(e1, e2, node.immediatelyInvoked)); + return transformIfUnchanged2( + node, + node.name, + node.function, + (e1, e2) => NamedFunction(e1, e2, node.immediatelyInvoked), + ); } @override Node visitNew(New node) { return transformIfUnchangedList1( - node, node.arguments, node.target, (e1, e2) => New(e2, e1)); + node, + node.arguments, + node.target, + (e1, e2) => New(e2, e1), + ); } @override Node visitObjectBindingPattern(ObjectBindingPattern node) { return transformIfUnchangedList( - node, node.variables, ObjectBindingPattern.new); + node, + node.variables, + ObjectBindingPattern.new, + ); } @override Node visitObjectInitializer(ObjectInitializer node) { - return transformIfUnchangedList(node, node.properties, - (e) => ObjectInitializer(e, multiline: node.multiline)); + return transformIfUnchangedList( + node, + node.properties, + (e) => ObjectInitializer(e, multiline: node.multiline), + ); } @override Node visitPostfix(Postfix node) { return transformIfUnchanged1( - node, node.argument, (e) => Postfix(node.op, e)); + node, + node.argument, + (e) => Postfix(node.op, e), + ); } @override Node visitPrefix(Prefix node) { return transformIfUnchanged1( - node, node.argument, (e) => Prefix(node.op, e)); + node, + node.argument, + (e) => Prefix(node.op, e), + ); } @override @@ -2793,8 +2952,12 @@ isUnchangedList(node.header, header)) { return node; } - return Program(body, - scriptTag: node.scriptTag, name: node.name, header: header); + return Program( + body, + scriptTag: node.scriptTag, + name: node.name, + header: header, + ); } @override @@ -2829,19 +2992,30 @@ @override Node visitSwitch(Switch node) { return transformIfUnchangedList1( - node, node.cases, node.key, (e1, e2) => Switch(e2, e1)); + node, + node.cases, + node.key, + (e1, e2) => Switch(e2, e1), + ); } @override Node visitTaggedTemplate(TaggedTemplate node) { return transformIfUnchanged2( - node, node.tag, node.template, TaggedTemplate.new); + node, + node.tag, + node.template, + TaggedTemplate.new, + ); } @override Node visitTemplateString(TemplateString node) { return transformIfUnchangedList( - node, node.interpolations, (e) => TemplateString(node.strings, e)); + node, + node.interpolations, + (e) => TemplateString(node.strings, e), + ); } @override @@ -2864,8 +3038,11 @@ @override Node visitVariableDeclarationList(VariableDeclarationList node) { - return transformIfUnchangedList(node, node.declarations, - (e) => VariableDeclarationList(node.keyword, e)); + return transformIfUnchangedList( + node, + node.declarations, + (e) => VariableDeclarationList(node.keyword, e), + ); } @override
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart index 485d7dc..ed8dc70 100644 --- a/pkg/dev_compiler/lib/src/js_ast/printer.dart +++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -18,12 +18,13 @@ /// Modern JS engines support this. final bool allowKeywordsInProperties; - JavaScriptPrintingOptions( - {this.shouldCompressOutput = false, - this.minifyLocalVariables = false, - this.preferSemicolonToNewlineInMinifiedOutput = false, - this.allowKeywordsInProperties = false, - this.allowSingleLineIfStatements = false}); + JavaScriptPrintingOptions({ + this.shouldCompressOutput = false, + this.minifyLocalVariables = false, + this.preferSemicolonToNewlineInMinifiedOutput = false, + this.allowKeywordsInProperties = false, + this.allowSingleLineIfStatements = false, + }); } /// An environment in which JavaScript printing is done. Provides emitting of @@ -92,14 +93,16 @@ static final expressionContinuationRegExp = RegExp(r'^[-+([]'); Printer(this.options, this.context, {LocalNamer? localNamer}) - : shouldCompressOutput = options.shouldCompressOutput, - danglingElseVisitor = DanglingElseVisitor(context), - localNamer = determineRenamer(localNamer, options) { + : shouldCompressOutput = options.shouldCompressOutput, + danglingElseVisitor = DanglingElseVisitor(context), + localNamer = determineRenamer(localNamer, options) { context.printer = this; } static LocalNamer determineRenamer( - LocalNamer? localNamer, JavaScriptPrintingOptions options) { + LocalNamer? localNamer, + JavaScriptPrintingOptions options, + ) { if (localNamer != null) return localNamer; return (options.shouldCompressOutput && options.minifyLocalVariables) ? MinifyRenamer() @@ -224,16 +227,24 @@ context.exitNode(node); } - void visitCommaSeparated(List<Expression> nodes, int hasRequiredType, - {required bool newInForInit, required bool newAtStatementBegin}) { + void visitCommaSeparated( + List<Expression> nodes, + int hasRequiredType, { + required bool newInForInit, + required bool newAtStatementBegin, + }) { for (int i = 0; i < nodes.length; i++) { if (i != 0) { atStatementBegin = false; out(','); spaceOut(); } - visitNestedExpression(nodes[i], hasRequiredType, - newInForInit: newInForInit, newAtStatementBegin: newAtStatementBegin); + visitNestedExpression( + nodes[i], + hasRequiredType, + newInForInit: newInForInit, + newAtStatementBegin: newAtStatementBegin, + ); } } @@ -249,8 +260,11 @@ visitAll(program.body); } - bool blockBody(Node body, - {required bool needsSeparation, required bool needsNewline}) { + bool blockBody( + Node body, { + required bool needsSeparation, + required bool needsNewline, + }) { if (body is Block) { spaceOut(); blockOut(body, shouldIndent: false, needsNewline: needsNewline); @@ -280,8 +294,11 @@ } } - void blockOut(Block node, - {required bool shouldIndent, required bool needsNewline}) { + void blockOut( + Block node, { + required bool shouldIndent, + required bool needsNewline, + }) { if (shouldIndent) indent(); context.enterNode(node); out('{'); @@ -308,8 +325,12 @@ @override void visitExpressionStatement(ExpressionStatement node) { indent(); - visitNestedExpression(node.expression, EXPRESSION, - newInForInit: false, newAtStatementBegin: true); + visitNestedExpression( + node.expression, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: true, + ); outSemicolonLn(); } @@ -336,8 +357,12 @@ out('if'); spaceOut(); out('('); - visitNestedExpression(node.condition, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node.condition, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); bool thenWasBlock; if (options.allowSingleLineIfStatements && !hasElse && then is! Block) { @@ -346,8 +371,11 @@ skipNextIndent(); visit(then); } else { - thenWasBlock = - blockBody(then, needsSeparation: false, needsNewline: !hasElse); + thenWasBlock = blockBody( + then, + needsSeparation: false, + needsNewline: !hasElse, + ); } if (hasElse) { if (thenWasBlock) { @@ -378,20 +406,32 @@ spaceOut(); out('('); if (loop.init != null) { - visitNestedExpression(loop.init!, EXPRESSION, - newInForInit: true, newAtStatementBegin: false); + visitNestedExpression( + loop.init!, + EXPRESSION, + newInForInit: true, + newAtStatementBegin: false, + ); } out(';'); if (loop.condition != null) { spaceOut(); - visitNestedExpression(loop.condition!, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + loop.condition!, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); } out(';'); if (loop.update != null) { spaceOut(); - visitNestedExpression(loop.update!, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + loop.update!, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); } out(')'); blockBody(loop.body, needsSeparation: false, needsNewline: true); @@ -402,12 +442,20 @@ outIndent('for'); spaceOut(); out('('); - visitNestedExpression(loop.leftHandSide, EXPRESSION, - newInForInit: true, newAtStatementBegin: false); + visitNestedExpression( + loop.leftHandSide, + EXPRESSION, + newInForInit: true, + newAtStatementBegin: false, + ); out(' in'); pendingSpace = true; - visitNestedExpression(loop.object, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + loop.object, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); blockBody(loop.body, needsSeparation: false, needsNewline: true); } @@ -417,12 +465,20 @@ outIndent('for'); spaceOut(); out('('); - visitNestedExpression(loop.leftHandSide, EXPRESSION, - newInForInit: true, newAtStatementBegin: false); + visitNestedExpression( + loop.leftHandSide, + EXPRESSION, + newInForInit: true, + newAtStatementBegin: false, + ); out(' of'); pendingSpace = true; - visitNestedExpression(loop.iterable, ASSIGNMENT, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + loop.iterable, + ASSIGNMENT, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); blockBody(loop.body, needsSeparation: false, needsNewline: true); } @@ -432,8 +488,12 @@ outIndent('while'); spaceOut(); out('('); - visitNestedExpression(loop.condition, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + loop.condition, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); blockBody(loop.body, needsSeparation: false, needsNewline: true); } @@ -449,8 +509,12 @@ out('while'); spaceOut(); out('('); - visitNestedExpression(loop.condition, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + loop.condition, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); outSemicolonLn(); } @@ -483,8 +547,12 @@ } else { outIndent('return'); pendingSpace = true; - visitNestedExpression(value, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + value, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); } outSemicolonLn(); } @@ -497,8 +565,12 @@ outIndent('yield'); } pendingSpace = true; - visitNestedExpression(node.expression, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node.expression, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); outSemicolonLn(); } @@ -506,8 +578,12 @@ void visitThrow(Throw node) { outIndent('throw'); pendingSpace = true; - visitNestedExpression(node.expression, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node.expression, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); outSemicolonLn(); } @@ -533,8 +609,12 @@ out('catch'); spaceOut(); out('('); - visitNestedExpression(node.declaration, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node.declaration, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); blockBody(node.body, needsSeparation: false, needsNewline: false); } @@ -544,8 +624,12 @@ outIndent('switch'); spaceOut(); out('('); - visitNestedExpression(node.key, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node.key, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); spaceOut(); outLn('{'); @@ -559,8 +643,12 @@ void visitCase(Case node) { outIndent('case'); pendingSpace = true; - visitNestedExpression(node.expression, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node.expression, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); outLn(':'); if (node.body.statements.isNotEmpty) { indentMore(); @@ -591,13 +679,21 @@ if (name != null) { out(' '); // Name must be a [Decl]. Therefore only test for primary expressions. - visitNestedExpression(name, PRIMARY, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + name, + PRIMARY, + newInForInit: false, + newAtStatementBegin: false, + ); } localNamer.enterScope(fun); out('('); - visitCommaSeparated(fun.params, PRIMARY, - newInForInit: false, newAtStatementBegin: false); + visitCommaSeparated( + fun.params, + PRIMARY, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); // When pattern support is enabled, case clauses like `case @@ -638,21 +734,25 @@ lineOut(); } - void visitNestedExpression(Expression node, int requiredPrecedence, - {required bool newInForInit, required bool newAtStatementBegin}) { + void visitNestedExpression( + Expression node, + int requiredPrecedence, { + required bool newInForInit, + required bool newAtStatementBegin, + }) { int precedenceLevel = node.precedenceLevel; bool needsParentheses = // a - (b + c). (requiredPrecedence != EXPRESSION && - precedenceLevel < requiredPrecedence) || - // for (a = (x in o); ... ; ... ) { ... } - (newInForInit && node is Binary && node.op == 'in') || - // (function() { ... })(). - // ({a: 2, b: 3}.toString()). - (newAtStatementBegin && - (node is NamedFunction || - node is FunctionExpression || - node is ObjectInitializer)); + precedenceLevel < requiredPrecedence) || + // for (a = (x in o); ... ; ... ) { ... } + (newInForInit && node is Binary && node.op == 'in') || + // (function() { ... })(). + // ({a: 2, b: 3}.toString()). + (newAtStatementBegin && + (node is NamedFunction || + node is FunctionExpression || + node is ObjectInitializer)); if (needsParentheses) { inForInit = false; atStatementBegin = false; @@ -674,23 +774,35 @@ out(list.keyword!); out(' '); } - visitCommaSeparated(list.declarations, ASSIGNMENT, - newInForInit: inForInit, newAtStatementBegin: false); + visitCommaSeparated( + list.declarations, + ASSIGNMENT, + newInForInit: inForInit, + newAtStatementBegin: false, + ); } @override void visitArrayBindingPattern(ArrayBindingPattern node) { out('['); - visitCommaSeparated(node.variables, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitCommaSeparated( + node.variables, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(']'); } @override void visitObjectBindingPattern(ObjectBindingPattern node) { out('{'); - visitCommaSeparated(node.variables, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitCommaSeparated( + node.variables, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out('}'); } @@ -717,8 +829,12 @@ spaceOut(); out('='); spaceOut(); - visitNestedExpression(defaultValue, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + defaultValue, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); } } @@ -729,46 +845,74 @@ @override void visitAssignment(Assignment assignment) { - visitNestedExpression(assignment.leftHandSide, LEFT_HAND_SIDE, - newInForInit: inForInit, newAtStatementBegin: atStatementBegin); + visitNestedExpression( + assignment.leftHandSide, + LEFT_HAND_SIDE, + newInForInit: inForInit, + newAtStatementBegin: atStatementBegin, + ); spaceOut(); String? op = assignment.op; if (op != null) out(op); out('='); spaceOut(); - visitNestedExpression(assignment.value, ASSIGNMENT, - newInForInit: inForInit, newAtStatementBegin: false); + visitNestedExpression( + assignment.value, + ASSIGNMENT, + newInForInit: inForInit, + newAtStatementBegin: false, + ); } @override void visitVariableInitialization(VariableInitialization initialization) { - visitNestedExpression(initialization.declaration, LEFT_HAND_SIDE, - newInForInit: inForInit, newAtStatementBegin: atStatementBegin); + visitNestedExpression( + initialization.declaration, + LEFT_HAND_SIDE, + newInForInit: inForInit, + newAtStatementBegin: atStatementBegin, + ); if (initialization.value != null) { spaceOut(); out('='); spaceOut(); - visitNestedExpression(initialization.value!, ASSIGNMENT, - newInForInit: inForInit, newAtStatementBegin: false); + visitNestedExpression( + initialization.value!, + ASSIGNMENT, + newInForInit: inForInit, + newAtStatementBegin: false, + ); } } @override void visitConditional(Conditional cond) { - visitNestedExpression(cond.condition, LOGICAL_OR, - newInForInit: inForInit, newAtStatementBegin: atStatementBegin); + visitNestedExpression( + cond.condition, + LOGICAL_OR, + newInForInit: inForInit, + newAtStatementBegin: atStatementBegin, + ); spaceOut(); out('?'); spaceOut(); // The then part is allowed to have an 'in'. - visitNestedExpression(cond.then, ASSIGNMENT, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + cond.then, + ASSIGNMENT, + newInForInit: false, + newAtStatementBegin: false, + ); context.expressionBranch(); spaceOut(); out(':'); spaceOut(); - visitNestedExpression(cond.otherwise, ASSIGNMENT, - newInForInit: inForInit, newAtStatementBegin: false); + visitNestedExpression( + cond.otherwise, + ASSIGNMENT, + newInForInit: inForInit, + newAtStatementBegin: false, + ); context.expressionJoin(); } @@ -776,22 +920,38 @@ void visitNew(New node) { out('new '); inNewTarget = true; - visitNestedExpression(node.target, ACCESS, - newInForInit: inForInit, newAtStatementBegin: false); + visitNestedExpression( + node.target, + ACCESS, + newInForInit: inForInit, + newAtStatementBegin: false, + ); inNewTarget = false; out('('); - visitCommaSeparated(node.arguments, SPREAD, - newInForInit: false, newAtStatementBegin: false); + visitCommaSeparated( + node.arguments, + SPREAD, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); } @override void visitCall(Call call) { - visitNestedExpression(call.target, LEFT_HAND_SIDE, - newInForInit: inForInit, newAtStatementBegin: atStatementBegin); + visitNestedExpression( + call.target, + LEFT_HAND_SIDE, + newInForInit: inForInit, + newAtStatementBegin: atStatementBegin, + ); out('('); - visitCommaSeparated(call.arguments, SPREAD, - newInForInit: false, newAtStatementBegin: false); + visitCommaSeparated( + call.arguments, + SPREAD, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); } @@ -886,8 +1046,12 @@ context.error('Forgot operator: $op'); } - visitNestedExpression(left, leftPrecedenceRequirement, - newInForInit: inForInit, newAtStatementBegin: atStatementBegin); + visitNestedExpression( + left, + leftPrecedenceRequirement, + newInForInit: inForInit, + newAtStatementBegin: atStatementBegin, + ); if (op == 'in' || op == 'instanceof') { // There are cases where the space is not required but without further @@ -900,8 +1064,12 @@ out(op); spaceOut(); } - visitNestedExpression(right, rightPrecedenceRequirement, - newInForInit: inForInit, newAtStatementBegin: false); + visitNestedExpression( + right, + rightPrecedenceRequirement, + newInForInit: inForInit, + newAtStatementBegin: false, + ); } @override @@ -929,8 +1097,12 @@ default: out(op); } - visitNestedExpression(unary.argument, unary.precedenceLevel, - newInForInit: inForInit, newAtStatementBegin: false); + visitNestedExpression( + unary.argument, + unary.precedenceLevel, + newInForInit: inForInit, + newAtStatementBegin: false, + ); } @override @@ -941,14 +1113,22 @@ out(yield.star ? 'yield*' : 'yield'); if (yield.value == null) return; out(' '); - visitNestedExpression(yield.value!, yield.precedenceLevel, - newInForInit: inForInit, newAtStatementBegin: false); + visitNestedExpression( + yield.value!, + yield.precedenceLevel, + newInForInit: inForInit, + newAtStatementBegin: false, + ); } @override void visitPostfix(Postfix postfix) { - visitNestedExpression(postfix.argument, LEFT_HAND_SIDE, - newInForInit: inForInit, newAtStatementBegin: atStatementBegin); + visitNestedExpression( + postfix.argument, + LEFT_HAND_SIDE, + newInForInit: inForInit, + newAtStatementBegin: atStatementBegin, + ); out(postfix.op); } @@ -1016,8 +1196,12 @@ /// int precedence = inNewTarget ? ACCESS : CALL; - visitNestedExpression(access.receiver, precedence, - newInForInit: inForInit, newAtStatementBegin: atStatementBegin); + visitNestedExpression( + access.receiver, + precedence, + newInForInit: inForInit, + newAtStatementBegin: atStatementBegin, + ); propertyNameOut(access.selector, inAccess: true); } @@ -1038,12 +1222,20 @@ void visitArrowFun(ArrowFun fun) { localNamer.enterScope(fun); if (fun.params.length == 1 && fun.params[0] is Identifier) { - visitNestedExpression(fun.params.single, SPREAD, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + fun.params.single, + SPREAD, + newInForInit: false, + newAtStatementBegin: false, + ); } else { out('('); - visitCommaSeparated(fun.params, SPREAD, - newInForInit: false, newAtStatementBegin: false); + visitCommaSeparated( + fun.params, + SPREAD, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); } spaceOut(); @@ -1056,8 +1248,12 @@ // https://tc39.github.io/ecma262/#sec-arrow-function-definitions var needsParen = body is ObjectInitializer; if (needsParen) out('('); - visitNestedExpression(body, ASSIGNMENT, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + body, + ASSIGNMENT, + newInForInit: false, + newAtStatementBegin: false, + ); if (needsParen) out(')'); } else { blockBody(body as Block, needsSeparation: false, needsNewline: false); @@ -1110,8 +1306,12 @@ forceLine(); indent(); } - visitNestedExpression(element, ASSIGNMENT, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + element, + ASSIGNMENT, + newInForInit: false, + newAtStatementBegin: false, + ); // We can skip the trailing "," for the last element (since it's not // an array hole). if (i != elements.length - 1) out(','); @@ -1167,8 +1367,12 @@ out(':'); } spaceOut(); - visitNestedExpression(node.value, ASSIGNMENT, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node.value, + ASSIGNMENT, + newInForInit: false, + newAtStatementBegin: false, + ); if (node.isClassProperty) { out(';'); } @@ -1251,8 +1455,12 @@ var fun = node.function; localNamer.enterScope(fun); out('('); - visitCommaSeparated(fun.params, SPREAD, - newInForInit: false, newAtStatementBegin: false); + visitCommaSeparated( + fun.params, + SPREAD, + newInForInit: false, + newAtStatementBegin: false, + ); out(')'); // TODO(jmesserly): async modifiers if (fun.body.statements.isEmpty) { @@ -1265,8 +1473,11 @@ localNamer.leaveScope(); } - void propertyNameOut(Expression node, - {bool inMethod = false, bool inAccess = false}) { + void propertyNameOut( + Expression node, { + bool inMethod = false, + bool inAccess = false, + }) { if (node is LiteralNumber) { LiteralNumber nameNumber = node; if (inAccess) out('['); @@ -1285,8 +1496,12 @@ } else { // ComputedPropertyName out('['); - visitNestedExpression(node, EXPRESSION, - newInForInit: false, newAtStatementBegin: false); + visitNestedExpression( + node, + EXPRESSION, + newInForInit: false, + newAtStatementBegin: false, + ); out(']'); } } @@ -1469,10 +1684,7 @@ final Set<String> vars; final Set<String> params; - VarCollector() - : nested = false, - vars = {}, - params = {}; + VarCollector() : nested = false, vars = {}, params = {}; void forEachVar(void Function(String) fn) => vars.forEach(fn); void forEachParam(void Function(String) fn) => params.forEach(fn);
diff --git a/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart b/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart index ba09c31..6b11aad 100644 --- a/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart +++ b/pkg/dev_compiler/lib/src/js_ast/source_map_printer.dart
@@ -92,7 +92,8 @@ emit('*/'); } else if (srcInfo is! NodeEnd) { throw StateError( - 'wrong kind of source map data: `$srcInfo` <${srcInfo.runtimeType}>'); + 'wrong kind of source map data: `$srcInfo` <${srcInfo.runtimeType}>', + ); } if (dartStart != null) { @@ -118,7 +119,8 @@ dartEnd = srcInfo.end; } else if (srcInfo is! SourceLocation && srcInfo is! HoverComment) { throw StateError( - 'wrong kind of source map data: `$srcInfo` <${srcInfo.runtimeType}>'); + 'wrong kind of source map data: `$srcInfo` <${srcInfo.runtimeType}>', + ); } if (dartEnd != null) { @@ -127,10 +129,13 @@ // at its exit, so this provides a mapping for that location. var column = _column - 1; if (column >= 0) { - // Adjust the column, because any ending brace or semicolon is already in - // the output. - var jsEnd = - SourceLocation(buffer.length - 1, line: _line, column: column); + // Adjust the column, because any ending brace or semicolon is already + // in the output. + var jsEnd = SourceLocation( + buffer.length - 1, + line: _line, + column: column, + ); _mark(dartEnd, jsEnd); } } else {
diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart index 663130a..db8b5e0 100644 --- a/pkg/dev_compiler/lib/src/js_ast/template.dart +++ b/pkg/dev_compiler/lib/src/js_ast/template.dart
@@ -17,8 +17,12 @@ } Template defineExpressionTemplate(String source, Node ast) { - Template template = - Template(source, ast, isExpression: true, forceCopy: false); + Template template = Template( + source, + ast, + isExpression: true, + forceCopy: false, + ); expressionTemplates[source] = template; return template; } @@ -28,8 +32,12 @@ } Template defineStatementTemplate(String source, Node ast) { - Template template = - Template(source, ast, isExpression: false, forceCopy: false); + Template template = Template( + source, + ast, + isExpression: false, + forceCopy: false, + ); statementTemplates[source] = template; return template; } @@ -53,15 +61,22 @@ bool get isPositional => holeNames.isEmpty; - Template._(this.source, this.ast, - {required this.instantiator, - required this.isExpression, - required this.forceCopy, - required this.positionalArgumentCount, - this.holeNames = const []}); + Template._( + this.source, + this.ast, { + required this.instantiator, + required this.isExpression, + required this.forceCopy, + required this.positionalArgumentCount, + this.holeNames = const [], + }); - factory Template(String? source, Node ast, - {bool isExpression = true, bool forceCopy = false}) { + factory Template( + String? source, + Node ast, { + bool isExpression = true, + bool forceCopy = false, + }) { assert(isExpression ? ast is Expression : ast is Statement); final generator = InstantiatorGeneratorVisitor(forceCopy); @@ -70,30 +85,39 @@ final names = generator.analysis.holeNames; final holeNames = names.toList(growable: false); - return Template._(source, ast, - instantiator: instantiator, - isExpression: isExpression, - forceCopy: forceCopy, - positionalArgumentCount: positionalArgumentCount, - holeNames: holeNames); + return Template._( + source, + ast, + instantiator: instantiator, + isExpression: isExpression, + forceCopy: forceCopy, + positionalArgumentCount: positionalArgumentCount, + holeNames: holeNames, + ); } factory Template.withExpressionResult(Expression ast) { assert(_checkNoPlaceholders(ast)); - return Template._(null, ast, - instantiator: (arguments) => ast, - isExpression: true, - forceCopy: false, - positionalArgumentCount: 0); + return Template._( + null, + ast, + instantiator: (arguments) => ast, + isExpression: true, + forceCopy: false, + positionalArgumentCount: 0, + ); } factory Template.withStatementResult(Statement ast) { assert(_checkNoPlaceholders(ast)); - return Template._(null, ast, - instantiator: (arguments) => ast, - isExpression: false, - forceCopy: false, - positionalArgumentCount: 0); + return Template._( + null, + ast, + instantiator: (arguments) => ast, + isExpression: false, + forceCopy: false, + positionalArgumentCount: 0, + ); } static bool _checkNoPlaceholders(Node ast) { @@ -125,8 +149,9 @@ throw 'Template arguments has unused mappings: $unusedNames'; } if (!holeNames.every((String name) => arguments.containsKey(name))) { - String notFound = - holeNames.where((name) => !arguments.containsKey(name)).join(', '); + String notFound = holeNames + .where((name) => !arguments.containsKey(name)) + .join(', '); throw 'Template arguments is missing mappings for: $notFound'; } return instantiator(arguments) as Node; @@ -157,7 +182,8 @@ return visit(node); } - static Instantiator<T> same<T extends Node>(T node) => (arguments) => node; + static Instantiator<T> same<T extends Node>(T node) => + (arguments) => node; static Null makeNull(dynamic arguments) => null; Instantiator visit<T extends Node>(T node) { @@ -184,14 +210,16 @@ @override Instantiator<Expression> visitInterpolatedExpression( - InterpolatedExpression node) { + InterpolatedExpression node, + ) { var nameOrPosition = node.nameOrPosition; return (arguments) { var value = arguments[nameOrPosition]; if (value is Expression) return value; if (value is String) return Identifier(value); throw StateError( - 'Interpolated value #$nameOrPosition is not an Expression: $value'); + 'Interpolated value #$nameOrPosition is not an Expression: $value', + ); }; } @@ -203,8 +231,10 @@ Expression toExpression(item) { if (item is Expression) return item; if (item is String) return Identifier(item); - throw StateError('Interpolated value #$nameOrPosition is not ' - 'an Expression or List of Expressions: $value'); + throw StateError( + 'Interpolated value #$nameOrPosition is not ' + 'an Expression or List of Expressions: $value', + ); } if (value is Iterable) return value.map(toExpression); @@ -236,7 +266,8 @@ var value = arguments[nameOrPosition]; if (value is Literal) return value; throw StateError( - 'Interpolated value #$nameOrPosition is not a Literal: $value'); + 'Interpolated value #$nameOrPosition is not a Literal: $value', + ); }; } @@ -250,8 +281,9 @@ if (item is Parameter) return item; if (item is String) return Identifier(item); throw StateError( - 'Interpolated value #$nameOrPosition is not an Identifier' - ' or List of Identifiers: $value'); + 'Interpolated value #$nameOrPosition is not an Identifier' + ' or List of Identifiers: $value', + ); } if (value is Iterable) return value.map(toIdentifier); @@ -261,7 +293,8 @@ @override Instantiator<Expression> visitInterpolatedSelector( - InterpolatedSelector node) { + InterpolatedSelector node, + ) { // A selector is an expression, as in `a[selector]`. // A String argument converted into a LiteralString, so `a.#` with argument // 'foo' generates `a["foo"]` which prints as `a.foo`. @@ -271,19 +304,22 @@ if (value is Expression) return value; if (value is String) return LiteralString('"$value"'); throw StateError( - 'Interpolated value #$nameOrPosition is not a selector: $value'); + 'Interpolated value #$nameOrPosition is not a selector: $value', + ); }; } @override Instantiator<Statement> visitInterpolatedStatement( - InterpolatedStatement node) { + InterpolatedStatement node, + ) { var nameOrPosition = node.nameOrPosition; return (arguments) { var value = arguments[nameOrPosition]; if (value is Node) return value.toStatement(); throw StateError( - 'Interpolated value #$nameOrPosition is not a Statement: $value'); + 'Interpolated value #$nameOrPosition is not a Statement: $value', + ); }; } @@ -294,8 +330,10 @@ var value = arguments[nameOrPosition]; Method toMethod(item) { if (item is Method) return item; - throw StateError('Interpolated value #$nameOrPosition is not a Method ' - 'or List of Methods: $value'); + throw StateError( + 'Interpolated value #$nameOrPosition is not a Method ' + 'or List of Methods: $value', + ); } if (value is Iterable) return value.map(toMethod); @@ -305,14 +343,17 @@ @override Instantiator<Identifier> visitInterpolatedIdentifier( - InterpolatedIdentifier node) { + InterpolatedIdentifier node, + ) { var nameOrPosition = node.nameOrPosition; return (arguments) { var item = arguments[nameOrPosition]; if (item is Identifier) return item; if (item is String) return Identifier(item); - throw StateError('Interpolated value #$nameOrPosition is not a ' - 'Identifier or String: $item'); + throw StateError( + 'Interpolated value #$nameOrPosition is not a ' + 'Identifier or String: $item', + ); }; } @@ -324,8 +365,10 @@ Statement toStatement(item) { if (item is Statement) return item; if (item is Expression) return item.toStatement(); - throw StateError('Interpolated value #$nameOrPosition is not ' - 'a Statement or List of Statements: $value'); + throw StateError( + 'Interpolated value #$nameOrPosition is not ' + 'a Statement or List of Statements: $value', + ); } if (value is Iterable) return value.map(toStatement); @@ -388,7 +431,9 @@ } Instantiator<Statement> visitIfConditionalCompilation( - If node, InterpolatedExpression condition) { + If node, + InterpolatedExpression condition, + ) { var makeThen = visit(node.then) as Instantiator<Statement>; var makeOtherwise = visit(node.otherwise) as Instantiator<Statement>; return (arguments) { @@ -398,8 +443,9 @@ if (value is bool) { return value ? makeThen(arguments) : makeOtherwise(arguments); } - var newCondition = - value is String ? Identifier(value) : value as Expression; + var newCondition = value is String + ? Identifier(value) + : value as Expression; return If(newCondition, makeThen(arguments), makeOtherwise(arguments)); }; } @@ -408,8 +454,11 @@ var makeCondition = visit(node.condition) as Instantiator<Expression>; var makeThen = visit(node.then) as Instantiator<Statement>; var makeOtherwise = visit(node.otherwise) as Instantiator<Statement>; - return (arguments) => If(makeCondition(arguments), makeThen(arguments), - makeOtherwise(arguments)); + return (arguments) => If( + makeCondition(arguments), + makeThen(arguments), + makeOtherwise(arguments), + ); } @override @@ -419,8 +468,12 @@ visitNullable(node.condition) as Instantiator<Expression>; var makeUpdate = visitNullable(node.update) as Instantiator<Expression>; var makeBody = visit(node.body) as Instantiator<Statement>; - return (arguments) => For(makeInit(arguments), makeCondition(arguments), - makeUpdate(arguments).toVoidExpression(), makeBody(arguments)); + return (arguments) => For( + makeInit(arguments), + makeCondition(arguments), + makeUpdate(arguments).toVoidExpression(), + makeBody(arguments), + ); } @override @@ -428,8 +481,11 @@ var makeLeftHandSide = visit(node.leftHandSide) as Instantiator<Expression>; var makeObject = visit(node.object) as Instantiator<Expression>; var makeBody = visit(node.body) as Instantiator<Statement>; - return (arguments) => ForIn(makeLeftHandSide(arguments), - makeObject(arguments), makeBody(arguments)); + return (arguments) => ForIn( + makeLeftHandSide(arguments), + makeObject(arguments), + makeBody(arguments), + ); } @override @@ -437,8 +493,11 @@ var makeLeftHandSide = visit(node.leftHandSide) as Instantiator<Expression>; var makeObject = visit(node.iterable) as Instantiator<Expression>; var makeBody = visit(node.body) as Instantiator<Statement>; - return (arguments) => ForOf(makeLeftHandSide(arguments), - makeObject(arguments), makeBody(arguments)); + return (arguments) => ForOf( + makeLeftHandSide(arguments), + makeObject(arguments), + makeBody(arguments), + ); } @override @@ -502,10 +561,13 @@ @override Instantiator<Switch> visitSwitch(Switch node) { var makeKey = visit(node.key) as Instantiator<Expression>; - var makeCases = - node.cases.map((c) => visit(c) as Instantiator<SwitchClause>); - return (arguments) => Switch(makeKey(arguments), - makeCases.map((makeCase) => makeCase(arguments)).toList()); + var makeCases = node.cases.map( + (c) => visit(c) as Instantiator<SwitchClause>, + ); + return (arguments) => Switch( + makeKey(arguments), + makeCases.map((makeCase) => makeCase(arguments)).toList(), + ); } @override @@ -527,7 +589,8 @@ @override Instantiator<FunctionDeclaration> visitFunctionDeclaration( - FunctionDeclaration node) { + FunctionDeclaration node, + ) { var makeName = visit(node.name) as Instantiator<Identifier>; var makeFunction = visit(node.function) as Instantiator<Fun>; return (arguments) => @@ -548,11 +611,15 @@ @override Instantiator<VariableDeclarationList> visitVariableDeclarationList( - VariableDeclarationList node) { - var declarationMakers = - node.declarations.map(visitVariableInitialization).toList(); + VariableDeclarationList node, + ) { + var declarationMakers = node.declarations + .map(visitVariableInitialization) + .toList(); return (arguments) => VariableDeclarationList( - node.keyword, declarationMakers.map((m) => m(arguments)).toList()); + node.keyword, + declarationMakers.map((m) => m(arguments)).toList(), + ); } @override @@ -561,19 +628,24 @@ String? op = node.op; Instantiator makeValue = visit(node.value); return (arguments) { - return makeValue(arguments) - .toAssignExpression(makeLeftHandSide(arguments), op) as Expression; + return makeValue( + arguments, + ).toAssignExpression(makeLeftHandSide(arguments), op) + as Expression; }; } @override Instantiator<VariableInitialization> visitVariableInitialization( - VariableInitialization node) { + VariableInitialization node, + ) { var makeDeclaration = visit(node.declaration) as Instantiator<VariableBinding>; var makeValue = visitNullable(node.value) as Instantiator<Expression?>; return (arguments) => VariableInitialization( - makeDeclaration(arguments), makeValue(arguments)); + makeDeclaration(arguments), + makeValue(arguments), + ); } @override @@ -581,8 +653,11 @@ var makeCondition = visit(cond.condition) as Instantiator<Expression>; var makeThen = visit(cond.then) as Instantiator<Expression>; var makeOtherwise = visit(cond.otherwise) as Instantiator<Expression>; - return (arguments) => Conditional(makeCondition(arguments), - makeThen(arguments), makeOtherwise(arguments)); + return (arguments) => Conditional( + makeCondition(arguments), + makeThen(arguments), + makeOtherwise(arguments), + ); } @override @@ -627,9 +702,11 @@ } @override - Instantiator<This> visitThis(This node) => (arguments) => This(); + Instantiator<This> visitThis(This node) => + (arguments) => This(); @override - Instantiator<Super> visitSuper(Super node) => (arguments) => Super(); + Instantiator<Super> visitSuper(Super node) => + (arguments) => Super(); @override Instantiator<Identifier> visitIdentifier(Identifier node) => @@ -675,8 +752,11 @@ var paramMakers = node.params.map(visitSplayable).toList(); var makeBody = visit(node.body) as Instantiator<Block>; return (arguments) => Fun( - splayNodes(paramMakers, arguments), makeBody(arguments), - isGenerator: node.isGenerator, asyncModifier: node.asyncModifier); + splayNodes(paramMakers, arguments), + makeBody(arguments), + isGenerator: node.isGenerator, + asyncModifier: node.asyncModifier, + ); } @override @@ -684,7 +764,9 @@ var paramMakers = node.params.map(visitSplayable).toList(); Instantiator makeBody = visit(node.body); return (arguments) => ArrowFun( - splayNodes(paramMakers, arguments), makeBody(arguments) as Node); + splayNodes(paramMakers, arguments), + makeBody(arguments) as Node, + ); } @override @@ -716,7 +798,8 @@ @override Instantiator<ObjectInitializer> visitObjectInitializer( - ObjectInitializer node) { + ObjectInitializer node, + ) { var propertyMakers = node.properties.map(visitSplayable).toList(); return (arguments) => ObjectInitializer(splayNodes(propertyMakers, arguments)); @@ -726,8 +809,12 @@ Instantiator<Property> visitProperty(Property node) { var makeName = visit(node.name) as Instantiator<Expression>; var makeValue = visit(node.value) as Instantiator<Expression>; - return (arguments) => Property(makeName(arguments), makeValue(arguments), - isStatic: node.isStatic, isClassProperty: node.isClassProperty); + return (arguments) => Property( + makeName(arguments), + makeValue(arguments), + isStatic: node.isStatic, + isClassProperty: node.isClassProperty, + ); } @override @@ -762,18 +849,24 @@ var makeHeritage = visitNullable(node.heritage) as Instantiator<Expression?>; - return (arguments) => ClassExpression(makeName(arguments), - makeHeritage(arguments), splayNodes(makeProperties, arguments)); + return (arguments) => ClassExpression( + makeName(arguments), + makeHeritage(arguments), + splayNodes(makeProperties, arguments), + ); } @override Instantiator<Method> visitMethod(Method node) { var makeName = visit(node.name) as Instantiator<Expression>; var makeFunction = visit(node.function) as Instantiator<Fun>; - return (arguments) => Method(makeName(arguments), makeFunction(arguments), - isGetter: node.isGetter, - isSetter: node.isSetter, - isStatic: node.isStatic); + return (arguments) => Method( + makeName(arguments), + makeFunction(arguments), + isGetter: node.isGetter, + isSetter: node.isSetter, + isStatic: node.isStatic, + ); } @override @@ -782,7 +875,8 @@ @override Instantiator<CommentExpression> visitCommentExpression( - CommentExpression node) { + CommentExpression node, + ) { var makeExpr = visit(node.expression) as Instantiator<Expression>; return (arguments) => CommentExpression(node.comment, makeExpr(arguments)); } @@ -811,7 +905,8 @@ @override Instantiator<DestructuredVariable> visitDestructuredVariable( - DestructuredVariable node) { + DestructuredVariable node, + ) { var makeName = visit(node.name) as Instantiator<Identifier>; var makeProperty = visitNullable(node.property) as Instantiator<Expression?>; @@ -820,29 +915,33 @@ var makeDefaultValue = visitNullable(node.defaultValue) as Instantiator<Expression?>; return (arguments) => DestructuredVariable( - name: makeName(arguments), - property: makeProperty(arguments), - structure: makeStructure(arguments), - defaultValue: makeDefaultValue(arguments)); + name: makeName(arguments), + property: makeProperty(arguments), + structure: makeStructure(arguments), + defaultValue: makeDefaultValue(arguments), + ); } @override Instantiator<ArrayBindingPattern> visitArrayBindingPattern( - ArrayBindingPattern node) { + ArrayBindingPattern node, + ) { List<Instantiator> makeVars = node.variables.map(visit).toList(); return (arguments) => ArrayBindingPattern(splayNodes(makeVars, arguments)); } @override Instantiator<ObjectBindingPattern> visitObjectBindingPattern( - ObjectBindingPattern node) { + ObjectBindingPattern node, + ) { List<Instantiator> makeVars = node.variables.map(visit).toList(); return (arguments) => ObjectBindingPattern(splayNodes(makeVars, arguments)); } @override Instantiator<SimpleBindingPattern> visitSimpleBindingPattern( - SimpleBindingPattern node) => + SimpleBindingPattern node, + ) => (arguments) => SimpleBindingPattern(Identifier(node.name.name)); }
diff --git a/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart b/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart index a98c543..c4c7ba4 100644 --- a/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart +++ b/pkg/dev_compiler/lib/src/kernel/asset_file_system.dart
@@ -25,26 +25,39 @@ /// /// Requests for `file:` entities continue to be resolved by [original]. AssetFileSystem(FileSystem original, String server, String port) - : this._(original, server, port); + : this._(original, server, port); /// Constructor used for unit tests. /// /// Changes the default the http client behavior to have no delay on retries, /// and allow specifying fewer total retries. - AssetFileSystem.forTesting(FileSystem original, String server, String port, - {required int retries}) - : this._(original, server, port, - retries: retries, delay: (_) => const Duration(seconds: 0)); + AssetFileSystem.forTesting( + FileSystem original, + String server, + String port, { + required int retries, + }) : this._( + original, + server, + port, + retries: retries, + delay: (_) => const Duration(seconds: 0), + ); - AssetFileSystem._(this.original, this.server, this.port, - {int? retries, Duration Function(int retryCount)? delay}) - : client = RetryTimeoutClient( - HttpClient() - ..maxConnectionsPerHost = 200 - ..connectionTimeout = const Duration(seconds: 30) - ..idleTimeout = const Duration(seconds: 30), - retries: retries ?? 4, - delay: delay); + AssetFileSystem._( + this.original, + this.server, + this.port, { + int? retries, + Duration Function(int retryCount)? delay, + }) : client = RetryTimeoutClient( + HttpClient() + ..maxConnectionsPerHost = 200 + ..connectionTimeout = const Duration(seconds: 30) + ..idleTimeout = const Duration(seconds: 30), + retries: retries ?? 4, + delay: delay, + ); /// Convert the uri to a server uri. Uri _resourceUri(Uri uri) => Uri.parse('http://$server:$port/${uri.path}'); @@ -91,7 +104,9 @@ if (response.statusCode != HttpStatus.ok) { unawaited(_ignore(response)); throw FileSystemException( - uri, 'Asset server returned ${response.statusCode}'); + uri, + 'Asset server returned ${response.statusCode}', + ); } return await collectBytes(response); }); @@ -107,7 +122,9 @@ if (response.statusCode != HttpStatus.ok) { unawaited(_ignore(response)); throw FileSystemException( - uri, 'Asset server returned ${response.statusCode}'); + uri, + 'Asset server returned ${response.statusCode}', + ); } return await response.transform(utf8.decoder).join(); }); @@ -118,7 +135,8 @@ /// Throws a [FileSystemException] on failure, /// and cleans up the client on return or error. Future<T> _runWithClient<T>( - Future<T> Function(RetryTimeoutClient httpClient) body) async { + Future<T> Function(RetryTimeoutClient httpClient) body, + ) async { try { return await body(fileSystem.client); } on Exception catch (e, s) {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index 04c61a0..09dd9e3 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -54,7 +54,7 @@ typedef _ArgumentGroups = ({ List<js_ast.Expression>? typeArguments, List<js_ast.Expression>? positionalArguments, - List<js_ast.Property>? namedArguments + List<js_ast.Property>? namedArguments, }); /// Public API for DDC compilers. @@ -64,8 +64,13 @@ Map<Member, String> get memberNames; Map<Procedure, js_ast.Identifier> get procedureIdentifiers; Map<VariableDeclaration, js_ast.Identifier> get variableIdentifiers; - js_ast.Fun emitFunctionIncremental(List<ModuleItem> items, Library library, - Class? cls, FunctionNode functionNode, String name); + js_ast.Fun emitFunctionIncremental( + List<ModuleItem> items, + Library library, + Class? cls, + FunctionNode functionNode, + String name, + ); } class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression> @@ -122,7 +127,7 @@ @override final variableIdentifiers = <VariableDeclaration, js_ast.Identifier>{}; - /// Identifiers for kernel variables with an analgous identifier in JS. + /// Identifiers for kernel variables with an analogous identifier in JS. /// /// [VariableDeclaration.name] is not necessarily a safe identifier for JS /// transpiled code. The same name can be used in shadowing contexts. We map @@ -344,8 +349,10 @@ final _privateNames = HashMap<Library, HashMap<String, js_ast.ScopedId>>(); /// Holds all top-level JS symbols (used for caching or indexing fields). - final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject('S', - keyToString: (js_ast.Identifier i) => i.name); + final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject( + 'S', + keyToString: (js_ast.Identifier i) => i.name, + ); /// Extension member symbols for adding Dart members to JS types. /// @@ -504,65 +511,104 @@ } ProgramCompiler._( - this._ticker, - this._coreTypes, - LibraryIndex sdk, - this._extensionTypes, - this._constants, - this._types, - this._hierarchy, - this._typeRep, - this._nullableInference, - this._staticTypeContext, - this._options, - this._importToSummary, - this._summaryToModule) - : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'), + this._ticker, + this._coreTypes, + LibraryIndex sdk, + this._extensionTypes, + this._constants, + this._types, + this._hierarchy, + this._typeRep, + this._nullableInference, + this._staticTypeContext, + this._options, + this._importToSummary, + this._summaryToModule, + ) : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'), _privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'), _linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'), - _identityHashMapImplClass = - sdk.getClass('dart:_js_helper', 'IdentityMap'), + _identityHashMapImplClass = sdk.getClass( + 'dart:_js_helper', + 'IdentityMap', + ), _linkedHashSetClass = sdk.getClass('dart:collection', 'LinkedHashSet'), _linkedHashSetImplClass = sdk.getClass('dart:_js_helper', 'LinkedSet'), - _identityHashSetImplClass = - sdk.getClass('dart:_js_helper', 'IdentitySet'), - _assertInteropMethod = - sdk.getTopLevelProcedure('dart:_runtime', 'assertInterop'), - _asyncStartMember = - sdk.getTopLevelMember('dart:async', '_asyncStartSync'), + _identityHashSetImplClass = sdk.getClass( + 'dart:_js_helper', + 'IdentitySet', + ), + _assertInteropMethod = sdk.getTopLevelProcedure( + 'dart:_runtime', + 'assertInterop', + ), + _asyncStartMember = sdk.getTopLevelMember( + 'dart:async', + '_asyncStartSync', + ), _asyncAwaitMember = sdk.getTopLevelMember('dart:async', '_asyncAwait'), _asyncReturnMember = sdk.getTopLevelMember('dart:async', '_asyncReturn'), - _asyncRethrowMember = - sdk.getTopLevelMember('dart:async', '_asyncRethrow'), - _asyncMakeCompleterMember = - sdk.getTopLevelMember('dart:async', '_makeAsyncAwaitCompleter'), - _asyncWrapJsFunctionMember = - sdk.getTopLevelMember('dart:async', '_wrapJsFunctionForAsync'), - _syncStarMakeIterableMember = - sdk.getTopLevelMember('dart:async', '_makeSyncStarIterable'), - _syncStarIteratorCurrentMember = - sdk.getMember('dart:async', '_SyncStarIterator', '_current'), - _syncStarIteratorDatumMember = - sdk.getMember('dart:async', '_SyncStarIterator', '_datum'), - _syncStarIteratorYieldStarMember = - sdk.getMember('dart:async', '_SyncStarIterator', '_yieldStar'), - _asyncStarHelperMember = - sdk.getTopLevelMember('dart:async', '_asyncStarHelper'), - _asyncStreamOfControllerMember = - sdk.getTopLevelMember('dart:async', '_streamOfController'), + _asyncRethrowMember = sdk.getTopLevelMember( + 'dart:async', + '_asyncRethrow', + ), + _asyncMakeCompleterMember = sdk.getTopLevelMember( + 'dart:async', + '_makeAsyncAwaitCompleter', + ), + _asyncWrapJsFunctionMember = sdk.getTopLevelMember( + 'dart:async', + '_wrapJsFunctionForAsync', + ), + _syncStarMakeIterableMember = sdk.getTopLevelMember( + 'dart:async', + '_makeSyncStarIterable', + ), + _syncStarIteratorCurrentMember = sdk.getMember( + 'dart:async', + '_SyncStarIterator', + '_current', + ), + _syncStarIteratorDatumMember = sdk.getMember( + 'dart:async', + '_SyncStarIterator', + '_datum', + ), + _syncStarIteratorYieldStarMember = sdk.getMember( + 'dart:async', + '_SyncStarIterator', + '_yieldStar', + ), + _asyncStarHelperMember = sdk.getTopLevelMember( + 'dart:async', + '_asyncStarHelper', + ), + _asyncStreamOfControllerMember = sdk.getTopLevelMember( + 'dart:async', + '_streamOfController', + ), _asyncMakeAsyncStarStreamControllerMember = sdk.getTopLevelMember( - 'dart:async', '_makeAsyncStarStreamController'), - _asyncIterationMarkerYieldSingleMember = - sdk.getMember('dart:async', '_IterationMarker', 'yieldSingle'), - _asyncIterationMarkerYieldStarMember = - sdk.getMember('dart:async', '_IterationMarker', 'yieldStar'), + 'dart:async', + '_makeAsyncStarStreamController', + ), + _asyncIterationMarkerYieldSingleMember = sdk.getMember( + 'dart:async', + '_IterationMarker', + 'yieldSingle', + ), + _asyncIterationMarkerYieldStarMember = sdk.getMember( + 'dart:async', + '_IterationMarker', + 'yieldStar', + ), _asyncStreamIteratorClass = sdk.getClass('dart:async', 'StreamIterator'), _futureOrNormalizer = FutureOrNormalizer(_coreTypes), _typeRecipeGenerator = TypeRecipeGenerator(_coreTypes, _hierarchy), - _extensionIndex = - ExtensionIndex(_coreTypes, _staticTypeContext.typeEnvironment), + _extensionIndex = ExtensionIndex( + _coreTypes, + _staticTypeContext.typeEnvironment, + ), _inlineTester = BasicInlineTester(_constants), _rtiLibrary = sdk.getLibrary('dart:_rti'), _rtiClass = sdk.getClass('dart:_rti', 'Rti'), @@ -622,7 +668,8 @@ m is Field ? m.isStatic : (m is Procedure ? m.isStatic : false); if (isStatic) return; var name = js_ast.toJSIdentifier( - m.name.text.replaceAll(js_ast.invalidCharInIdentifier, '_')); + m.name.text.replaceAll(js_ast.invalidCharInIdentifier, '_'), + ); uniqueNames.add(name); }); }); @@ -655,7 +702,7 @@ _constTable, js_ast.LiteralString('_'), _constTableCache.containerId, - _constTable + _constTable, ]); _moduleItems.add(constTableDeclaration); @@ -684,8 +731,10 @@ _moduleItems.insertAll(safeDeclarationIndex, _constTableCache.emit()); if (_constLazyAccessors.isNotEmpty) { - var constTableBody = _runtimeStatement( - 'defineLazy(#, { # })', [_constTable, _constLazyAccessors]); + var constTableBody = _runtimeStatement('defineLazy(#, { # })', [ + _constTable, + _constLazyAccessors, + ]); _moduleItems.insert(_constTableInsertionIndex, constTableBody); _constLazyAccessors.clear(); } @@ -695,10 +744,12 @@ // Register the local const cache for this module so it can be cleared on a // hot restart. if (_constTableCache.isNotEmpty) { - _moduleItems.add(_runtimeCall('moduleConstCaches.set(#, #)', [ - js_ast.string(_options.moduleName), - _constTableCache.containerId - ]).toStatement()); + _moduleItems.add( + _runtimeCall('moduleConstCaches.set(#, #)', [ + js_ast.string(_options.moduleName), + _constTableCache.containerId, + ]).toStatement(), + ); } _ticker?.logMs('Added table caches'); // Add all type hierarchy rules for the interface types used in this module. @@ -717,27 +768,29 @@ _typeRecipeGenerator.addLiveTypeAncestries(type); } } - var universeClass = - _rtiLibrary.classes.firstWhere((cls) => cls.name == '_Universe'); + var universeClass = _rtiLibrary.classes.firstWhere( + (cls) => cls.name == '_Universe', + ); var typeRules = _typeRecipeGenerator.liveInterfaceTypeRules; var legacyJavaScriptObjectRecipe = _typeRecipeGenerator.interfaceTypeRecipe( - _coreTypes.index - .getClass('dart:_interceptors', 'LegacyJavaScriptObject')); - var legacyJavaScriptObjectRules = - typeRules.remove(legacyJavaScriptObjectRecipe); + _coreTypes.index.getClass('dart:_interceptors', 'LegacyJavaScriptObject'), + ); + var legacyJavaScriptObjectRules = typeRules.remove( + legacyJavaScriptObjectRecipe, + ); if (typeRules.isNotEmpty) { var template = '#._Universe.#(#, JSON.parse(#))'; var addRulesStatement = js.call(template, [ _emitLibraryName(_rtiLibrary), _emitMemberName('addRules', memberClass: universeClass), _runtimeCall('typeUniverse'), - js.string(jsonEncode(typeRules), "'") + js.string(jsonEncode(typeRules), "'"), ]).toStatement(); _moduleItems.add(addRulesStatement); } if (legacyJavaScriptObjectRules != null) { var legacyJavaScriptObjectAddRules = { - legacyJavaScriptObjectRecipe: legacyJavaScriptObjectRules + legacyJavaScriptObjectRecipe: legacyJavaScriptObjectRules, }; // The recipe for 'LegacyJavaScriptObject' is updated during the lifetime // of the program and should be emitted with 'addOrUpdateRules' to avoid @@ -747,7 +800,7 @@ _emitLibraryName(_rtiLibrary), _emitMemberName('addOrUpdateRules', memberClass: universeClass), _runtimeCall('typeUniverse'), - js.string(jsonEncode(legacyJavaScriptObjectAddRules), "'") + js.string(jsonEncode(legacyJavaScriptObjectAddRules), "'"), ]); _moduleItems.add(updateRulesStatement); } @@ -765,7 +818,7 @@ _emitLibraryName(_rtiLibrary), _emitMemberName('addOrUpdateRules', memberClass: universeClass), _runtimeCall('typeUniverse'), - js.string(jsonEncode(updateRules), "'") + js.string(jsonEncode(updateRules), "'"), ]); _moduleItems.add(updateRulesStatement); } @@ -774,17 +827,24 @@ // Update the `LegacyJavaScriptObject` class with the type tags for all // interop types in this module. This is the quick path for simple type // tests that matches the rules encoded above. - var legacyJavaScriptObjectClass = _coreTypes.index - .getClass('dart:_interceptors', 'LegacyJavaScriptObject'); + var legacyJavaScriptObjectClass = _coreTypes.index.getClass( + 'dart:_interceptors', + 'LegacyJavaScriptObject', + ); var legacyJavaScriptObjectClassRef = _emitClassRef( - legacyJavaScriptObjectClass.getThisType( - _coreTypes, Nullability.nonNullable)); + legacyJavaScriptObjectClass.getThisType( + _coreTypes, + Nullability.nonNullable, + ), + ); var interopRecipesArray = js_ast.stringArray([ _typeRecipeGenerator.interfaceTypeRecipe(legacyJavaScriptObjectClass), - ...jsInteropTypeRecipes + ...jsInteropTypeRecipes, ]); - var jsInteropRules = _runtimeStatement('addRtiResources(#, #)', - [legacyJavaScriptObjectClassRef, interopRecipesArray]); + var jsInteropRules = _runtimeStatement('addRtiResources(#, #)', [ + legacyJavaScriptObjectClassRef, + interopRecipesArray, + ]); _moduleItems.add(jsInteropRules); } @@ -795,10 +855,12 @@ var addTypeParameterVariancesStatement = js.call(addTypeParameterVariancesTemplate, [ _emitLibraryName(_rtiLibrary), - _emitMemberName('addTypeParameterVariances', - memberClass: universeClass), + _emitMemberName( + 'addTypeParameterVariances', + memberClass: universeClass, + ), _runtimeCall('typeUniverse'), - js.string(jsonEncode(typeVariances), "'") + js.string(jsonEncode(typeVariances), "'"), ]).toStatement(); _moduleItems.add(addTypeParameterVariancesStatement); } @@ -807,15 +869,16 @@ // eagerly with 'findType' (without normalization) to avoid infinite loops. // See normalization functions in: sdk/lib/_internal/js_shared/lib/rti.dart if (_isBuildingSdk) { - var prerequisiteRtiTypes = [ - _coreTypes.objectNullableRawType, - ]; + var prerequisiteRtiTypes = [_coreTypes.objectNullableRawType]; prerequisiteRtiTypes.forEach((type) { var recipe = _typeRecipeGenerator .recipeInEnvironment(type, EmptyTypeEnvironment()) .recipe; - _moduleItems.add(js.call('#.findType("$recipe")', - [_emitLibraryName(_rtiLibrary)]).toStatement()); + _moduleItems.add( + js.call('#.findType("$recipe")', [ + _emitLibraryName(_rtiLibrary), + ]).toStatement(), + ); }); } @@ -824,17 +887,23 @@ _ticker?.logMs('Emitted exports'); // Declare imports and extension symbols - _emitImportsAndExtensionSymbols(items, - forceExtensionSymbols: - libraries.any((l) => allowedNativeTest(l.importUri))); + _emitImportsAndExtensionSymbols( + items, + forceExtensionSymbols: libraries.any( + (l) => allowedNativeTest(l.importUri), + ), + ); _ticker?.logMs('Emitted imports and extension symbols'); // Emit the hoisted type table cache variables items.addAll(_typeTable.dischargeBoundTypes()); _ticker?.logMs('Emitted type table'); - var module = _finishModule(items, _options.moduleName, - header: _generateCompilationHeader()); + var module = _finishModule( + items, + _options.moduleName, + header: _generateCompilationHeader(), + ); _ticker?.logMs('Finished emitting module'); // Mark as finished for incremental mode, so it is safe to @@ -905,8 +974,10 @@ var moduleName = _summaryToModule[summary]; if (moduleName == null) { if (throwIfNotFound) { - throw StateError('Could not find module name for library "$library" ' - 'from component "$summary".'); + throw StateError( + 'Could not find module name for library "$library" ' + 'from component "$summary".', + ); } return ''; } @@ -930,8 +1001,10 @@ if (_isSdkInternalRuntime(library)) { // Add embedded globals. _moduleItems.add( - _runtimeCall('typeUniverse = #', [js_ast.createRtiUniverse()]) - .toStatement()); + _runtimeCall('typeUniverse = #', [ + js_ast.createRtiUniverse(), + ]).toStatement(), + ); // `dart:_runtime` uses a different order for bootstrapping. // // Functions are first because we use them to associate type info @@ -955,8 +1028,11 @@ // serves as a signal to V8 that the members of the library should get // optimized for fast lookup. // Do not remove without testing for performance regressions. - _moduleItems.add(js.statement( - '(function() {}).prototype = #', [_libraries[_currentLibrary!]])); + _moduleItems.add( + js.statement('(function() {}).prototype = #', [ + _libraries[_currentLibrary!], + ]), + ); _staticTypeContext.leaveLibrary(_currentLibrary!); _currentLibrary = null; } @@ -980,8 +1056,13 @@ if (node is Procedure && node.name.text == 'main') { // Don't allow redefining names from this library. var name = _emitTopLevelName(node); - _moduleItems.add(js.statement( - '#.# = #;', [_emitLibraryName(library), name.selector, name])); + _moduleItems.add( + js.statement('#.# = #;', [ + _emitLibraryName(library), + name.selector, + name, + ]), + ); } } @@ -1013,7 +1094,9 @@ // (see [_emitMixinStatement]). if (c.isMixinDeclaration && !c.isMixinClass) { _mixinSuperclassCache.putIfAbsent( - c, () => _emitScopedId(getLocalClassName(c.superclass!))); + c, + () => _emitScopedId(getLocalClassName(c.superclass!)), + ); } // Mixins are unrolled in _defineClass. @@ -1058,15 +1141,21 @@ static js_ast.Identifier _emitIdentifier(String name) => js_ast.Identifier(js_ast.toJSIdentifier(name)); - static js_ast.ScopedId _emitScopedId(String name, - {bool needsCapture = false}) => + static js_ast.ScopedId _emitScopedId( + String name, { + bool needsCapture = false, + }) => js_ast.ScopedId(js_ast.toJSIdentifier(name), needsCapture: needsCapture); js_ast.Statement _emitClassDeclaration(Class c) { var className = _emitTopLevelNameNoExternalInterop(c); var savedClassProperties = _classProperties; - _classProperties = - ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, c); + _classProperties = ClassPropertyModel.build( + _types, + _extensionTypes, + _virtualFields, + c, + ); var body = <js_ast.Statement>[]; @@ -1079,7 +1168,11 @@ // assign directly to [virtualField]. If the latter, copy the old // variable to [virtualField]. var symbol = _emitClassPrivateNameSymbol( - c.enclosingLibrary, getLocalClassName(c), field, virtualField); + c.enclosingLibrary, + getLocalClassName(c), + field, + virtualField, + ); if (symbol != virtualField) { _addSymbol(virtualField, _getSymbolValue(symbol)); if (!_containerizeSymbols) { @@ -1100,11 +1193,12 @@ // We only need to tag static functions that are torn off at // compile-time. We attach these late so tearoffs have access to // their types. - var reifiedType = member.function - .computeThisFunctionType(member.enclosingLibrary.nonNullable); + var reifiedType = member.function.computeThisFunctionType( + member.enclosingLibrary.nonNullable, + ); jsStaticMethodTypeTags.add( - _emitFunctionTagged(result, reifiedType, asLazy: true) - .toStatement()); + _emitFunctionTagged(result, reifiedType, asLazy: true).toStatement(), + ); } } @@ -1152,10 +1246,14 @@ var implementedRecipes = [ name, for (var type in transitiveImplementedTypes(c)) - _typeRecipeGenerator.interfaceTypeRecipe(type.classNode) + _typeRecipeGenerator.interfaceTypeRecipe(type.classNode), ]; - body.add(_runtimeStatement('addRtiResources(#, #)', - [className, js_ast.stringArray(implementedRecipes)])); + body.add( + _runtimeStatement('addRtiResources(#, #)', [ + className, + js_ast.stringArray(implementedRecipes), + ]), + ); _emitClassSignature(c, className, body); _initExtensionSymbols(c); if (!c.isMixinDeclaration) { @@ -1166,8 +1264,11 @@ var evaluatedDeferredSupertypes = deferredSupertypes.map<js_ast.Statement>((f) => f()).toList(); if (typeFormals.isNotEmpty) { - var genericClassStmts = _defineGenericClass(typeFormals, - js_ast.Statement.from(body), evaluatedDeferredSupertypes); + var genericClassStmts = _defineGenericClass( + typeFormals, + js_ast.Statement.from(body), + evaluatedDeferredSupertypes, + ); body = [...genericClassStmts]; } else { _afterClassDefItems.addAll(evaluatedDeferredSupertypes); @@ -1221,13 +1322,20 @@ // Note that this class has no heritage. This class should never be used // as a type. It's merely a placeholder for static members. var body = <js_ast.Statement>[ - _emitClassStatement(c, className, null, nonExternalMethods) - .toStatement() + _emitClassStatement( + c, + className, + null, + nonExternalMethods, + ).toStatement(), ]; var typeFormals = c.typeParameters; if (typeFormals.isNotEmpty) { - var genericClassStmts = - _defineGenericClass(typeFormals, js_ast.Statement.from(body), []); + var genericClassStmts = _defineGenericClass( + typeFormals, + js_ast.Statement.from(body), + [], + ); body = [...genericClassStmts, ...fieldInitialization]; } else { body = [...body, ...fieldInitialization]; @@ -1238,8 +1346,11 @@ } /// Emits a generic class with additional initialization logic. - List<js_ast.Statement> _defineGenericClass(List<TypeParameter> formals, - js_ast.Statement body, List<js_ast.Statement> deferredBaseClass) { + List<js_ast.Statement> _defineGenericClass( + List<TypeParameter> formals, + js_ast.Statement body, + List<js_ast.Statement> deferredBaseClass, + ) { assert(formals.isNotEmpty); return [ ..._typeTable.dischargeFreeTypes(formals), @@ -1248,8 +1359,12 @@ ]; } - js_ast.Statement _emitClassStatement(Class c, js_ast.Expression className, - js_ast.Expression? heritage, List<js_ast.Method> methods) { + js_ast.Statement _emitClassStatement( + Class c, + js_ast.Expression className, + js_ast.Expression? heritage, + List<js_ast.Method> methods, + ) { var classIdentifier = _emitScopedId(getLocalClassName(c)); if (_options.emitDebugSymbols) classIdentifiers[c] = classIdentifier; var classExpr = js_ast.ClassExpression(classIdentifier, heritage, methods); @@ -1284,11 +1399,12 @@ /// unnecessary class, but for now, this lets us get the right semantics with /// minimal compiler and runtime changes. void _emitMixinStatement( - Class c, - js_ast.Expression className, - js_ast.Expression heritage, - List<js_ast.Method> methods, - List<js_ast.Statement> body) { + Class c, + js_ast.Expression className, + js_ast.Expression heritage, + List<js_ast.Method> methods, + List<js_ast.Statement> body, + ) { var staticMethods = methods.where((m) => m.isStatic).toList(); var instanceMethods = methods.where((m) => !m.isStatic).toList(); @@ -1298,8 +1414,11 @@ ? className : _emitScopedId(getLocalClassName(c)); - var mixinMemberClass = - js_ast.ClassExpression(classId, superclassId, instanceMethods); + var mixinMemberClass = js_ast.ClassExpression( + classId, + superclassId, + instanceMethods, + ); js_ast.Node arrowFnBody = mixinMemberClass; var extensionInit = <js_ast.Statement>[]; @@ -1310,19 +1429,22 @@ arrowFnBody = js_ast.Block(extensionInit); } - body.add(js.statement('#[#] = #', [ - className, - _runtimeCall('mixinOn'), - js_ast.ArrowFun([superclassId], arrowFnBody) - ])); + body.add( + js.statement('#[#] = #', [ + className, + _runtimeCall('mixinOn'), + js_ast.ArrowFun([superclassId], arrowFnBody), + ]), + ); } void _defineClass( - Class c, - js_ast.Expression className, - List<js_ast.Method> methods, - List<js_ast.Statement> body, - List<js_ast.Statement Function()> deferredSupertypes) { + Class c, + js_ast.Expression className, + List<js_ast.Method> methods, + List<js_ast.Statement> body, + List<js_ast.Statement Function()> deferredSupertypes, + ) { if (c == _coreTypes.objectClass) { body.add(_emitClassStatement(c, className, null, methods)); return; @@ -1376,8 +1498,12 @@ var hasUnnamedSuper = _hasUnnamedInheritedConstructor(superclass); - void emitMixinConstructors(js_ast.Expression className, - Class mixinSuperclass, Class mixinClass, InterfaceType mixin) { + void emitMixinConstructors( + js_ast.Expression className, + Class mixinSuperclass, + Class mixinClass, + InterfaceType mixin, + ) { for (var ctor in mixinSuperclass.constructors) { var savedUri = _currentUri; _currentUri = ctor.enclosingClass.fileUri; @@ -1385,12 +1511,12 @@ var sharedParams = _emitParameters(ctor.function, isForwarding: true); var mixinConstructorParams = [ if (_requiresRtiForInstantiation(mixinSuperclass)) _rtiParam, - ...sharedParams + ...sharedParams, ]; var superConstructorArgs = [ if (_requiresRtiForInstantiation(ctor.enclosingClass)) js_ast.LiteralNull(), - ...sharedParams + ...sharedParams, ]; js_ast.Statement? mixinCtor; @@ -1412,11 +1538,21 @@ if (mixinCtor != null) mixinCtor, if (name != '' || hasUnnamedSuper) _emitSuperConstructorCall( - ctor, className, name, superConstructorArgs), + ctor, + className, + name, + superConstructorArgs, + ), ]; // TODO(nshahan) Record the name for this constructor in memberNames. - body.add(_addConstructorToClass(c, className, _constructorName(name), - js_ast.Fun(mixinConstructorParams, js_ast.Block(ctorBody)))); + body.add( + _addConstructorToClass( + c, + className, + _constructorName(name), + js_ast.Fun(mixinConstructorParams, js_ast.Block(ctorBody)), + ), + ); _currentUri = savedUri; } } @@ -1443,12 +1579,16 @@ // Collect all forwarding stub members from anonymous mixins classes. // These can contain covariant parameter checks that need to be applied. var savedClassProperties = _classProperties; - _classProperties = - ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, m); + _classProperties = ClassPropertyModel.build( + _types, + _extensionTypes, + _virtualFields, + m, + ); var forwardingMembers = { for (var procedure in m.procedures) if (procedure.isForwardingStub && !procedure.isAbstract) - procedure.name.text: procedure + procedure.name.text: procedure, }; // Mixin applications can introduce their own reference to the type // parameters from the class being mixed in and their use can appear in @@ -1484,26 +1624,41 @@ // this operation is that mixin IDs are renamed by the local visitor. We // can remove this hoisting after we give mixins unique names. var enclosingLibrary = _emitLibraryName(_currentLibrary!); - var mixinAccessor = - js_ast.PropertyAccess(enclosingLibrary, js.string(mixinId.name)); + var mixinAccessor = js_ast.PropertyAccess( + enclosingLibrary, + js.string(mixinId.name), + ); body.addAll([ js.statement('const # = #', [ mixinId, - js_ast.ClassExpression(_emitScopedId('${mixinId.name}\$'), baseClass, - forwardingMethodStubs) + js_ast.ClassExpression( + _emitScopedId('${mixinId.name}\$'), + baseClass, + forwardingMethodStubs, + ), ]), - js.statement('# = #', [mixinAccessor, mixinId]) + js.statement('# = #', [mixinAccessor, mixinId]), ]); emitMixinConstructors(mixinId, superclass, mixinClass, mixinType); hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(mixinClass); var mixinTargetLabel = js.string(fullyResolvedMixinClassLabel(m)); if (shouldDefer(mixinType)) { - deferredSupertypes.add(() => _runtimeStatement('applyMixin(#, #, #)', - [mixinId, emitDeferredClassRef(mixinType), mixinTargetLabel])); + deferredSupertypes.add( + () => _runtimeStatement('applyMixin(#, #, #)', [ + mixinId, + emitDeferredClassRef(mixinType), + mixinTargetLabel, + ]), + ); } else { - body.add(_runtimeStatement('applyMixin(#, #, #)', - [mixinId, emitClassRef(mixinType), baseClass])); + body.add( + _runtimeStatement('applyMixin(#, #, #)', [ + mixinId, + emitClassRef(mixinType), + baseClass, + ]), + ); } baseClass = mixinId; @@ -1520,7 +1675,9 @@ /// Defines all constructors for this class as ES5 constructors. List<js_ast.Statement> _defineConstructors( - Class c, js_ast.Expression className) { + Class c, + js_ast.Expression className, + ) { var body = <js_ast.Statement>[]; if (c.isAnonymousMixin) { // We already handled this when we defined the class. @@ -1537,7 +1694,9 @@ var constructorName = _constructorName(ctor.name.text); memberNames[ctor] = constructorName.valueWithoutQuotes; addConstructor( - constructorName, _emitConstructor(ctor, fields, className)); + constructorName, + _emitConstructor(ctor, fields, className), + ); } // If classElement has only factory constructors, and it can be mixed in, @@ -1545,19 +1704,22 @@ // mixins. if (_usesMixinNew(c)) { body.add( - js.statement('(#[#] = function() { # }).prototype = #.prototype;', [ - className, - _runtimeCall('mixinNew'), - [_initializeFields(fields)], - className - ])); + js.statement('(#[#] = function() { # }).prototype = #.prototype;', [ + className, + _runtimeCall('mixinNew'), + [_initializeFields(fields)], + className, + ]), + ); } return body; } void _emitDartSymbols( - Iterable<js_ast.ScopedId> vars, List<js_ast.ModuleItem> body) { + Iterable<js_ast.ScopedId> vars, + List<js_ast.ModuleItem> body, + ) { for (var id in vars) { body.add(js.statement('const # = Symbol(#)', [id, js.string(id.name)])); } @@ -1565,7 +1727,9 @@ void _emitSuperHelperSymbols(List<js_ast.Statement> body) { _emitDartSymbols( - _superHelpers.values.map((m) => m.name as js_ast.ScopedId), body); + _superHelpers.values.map((m) => m.name as js_ast.ScopedId), + body, + ); _superHelpers.clear(); } @@ -1575,11 +1739,17 @@ var fields = c.fields.where((f) => f.isStatic && !f.isExternal).toList(); var fieldNames = Set.of(fields.map((f) => f.name)); var staticSetters = c.procedures.where( - (p) => p.isStatic && p.isAccessor && fieldNames.contains(p.name)); + (p) => p.isStatic && p.isAccessor && fieldNames.contains(p.name), + ); var members = [...fields, ...staticSetters]; if (fields.isNotEmpty) { - body.add(_emitLazyMembers(_emitTopLevelNameNoExternalInterop(c), members, - (n) => _emitStaticMemberName(n.name.text))); + body.add( + _emitLazyMembers( + _emitTopLevelNameNoExternalInterop(c), + members, + (n) => _emitStaticMemberName(n.name.text), + ), + ); } } @@ -1597,17 +1767,21 @@ /// If a concrete class implements one of our extensions, we might need to /// add forwarders. void _defineExtensionMembers( - js_ast.Expression className, List<js_ast.Statement> body) { + js_ast.Expression className, + List<js_ast.Statement> body, + ) { void emitExtensions(String helperName, Iterable<String> extensions) { if (extensions.isEmpty) return; var names = extensions .map((e) => _propertyName(js_ast.memberNameForDartMember(e))) .toList(); - body.add(_runtimeStatement('#(#, #)', [ - helperName, - className, - js_ast.ArrayInitializer(names, multiline: names.length > 4) - ])); + body.add( + _runtimeStatement('#(#, #)', [ + helperName, + className, + js_ast.ArrayInitializer(names, multiline: names.length > 4), + ]), + ); } var props = _classProperties!; @@ -1617,10 +1791,14 @@ /// Emit the signature on the class recording the runtime type information void _emitClassSignature( - Class c, js_ast.Expression className, List<js_ast.Statement> body) { + Class c, + js_ast.Expression className, + List<js_ast.Statement> body, + ) { var savedTypeEnvironment = _currentTypeEnvironment; - _currentTypeEnvironment = - RtiTypeEnvironment(_currentTypeEnvironment.classTypeParameters); + _currentTypeEnvironment = RtiTypeEnvironment( + _currentTypeEnvironment.classTypeParameters, + ); var savedClass = _classEmittingSignatures; _classEmittingSignatures = c; @@ -1632,23 +1810,26 @@ var proto = c == _coreTypes.objectClass ? js.call('Object.create(null)') : _runtimeCall('get${name}s(#)', [ - _emitJSObjectGetPrototypeOf(className, fullyQualifiedName: true) + _emitJSObjectGetPrototypeOf( + className, + fullyQualifiedName: true, + ), ]); setSignature = _runtimeStatement('set${name}Signature(#, () => #)', [ className, _emitJSObjectSetPrototypeOf( - js_ast.ObjectInitializer(elements, - multiline: elements.length > 1), - proto, - fullyQualifiedName: true) + js_ast.ObjectInitializer(elements, multiline: elements.length > 1), + proto, + fullyQualifiedName: true, + ), ]); } else { // TODO(40273) Only tagging with the names of static members until the // debugger consumes signature information from symbol files. setSignature = _runtimeStatement('set${name}Signature(#, () => #)', [ className, - js_ast.ArrayInitializer(elements.map((e) => e.name).toList()) + js_ast.ArrayInitializer(elements.map((e) => e.name).toList()), ]); } @@ -1656,22 +1837,32 @@ } js_ast.Expression emitClassFieldSignature(Field field, Class fromClass) { - var fieldType = - _typeFromClass(field.type, field.enclosingClass!, fromClass) - .extensionTypeErasure; + var fieldType = _typeFromClass( + field.type, + field.enclosingClass!, + fromClass, + ).extensionTypeErasure; var uri = fieldType is InterfaceType ? _cacheUri( - _jsLibraryDebuggerName(fieldType.classNode.enclosingLibrary)) + _jsLibraryDebuggerName(fieldType.classNode.enclosingLibrary), + ) : null; var isConst = js.boolean(field.isConst); var isFinal = js.boolean(field.isFinal); var type = _emitType(fieldType); var typeResolver = js_ast.ArrowFun([_rtiParam], type); return uri == null - ? js('{type: #, isConst: #, isFinal: #}', - [typeResolver, isConst, isFinal]) - : js('{type: #, isConst: #, isFinal: #, libraryUri: #}', - [typeResolver, isConst, isFinal, uri]); + ? js('{type: #, isConst: #, isFinal: #}', [ + typeResolver, + isConst, + isFinal, + ]) + : js('{type: #, isConst: #, isFinal: #, libraryUri: #}', [ + typeResolver, + isConst, + isFinal, + uri, + ]); } var extMethods = _classProperties!.extensionMethods; @@ -1726,8 +1917,11 @@ // emit a signature on this class. Otherwise we will inherit the // signature from the superclass. var memberOverride = c.superclass != null - ? _hierarchy.getDispatchTarget(c.superclass!, member.name, - setter: member.isSetter) + ? _hierarchy.getDispatchTarget( + c.superclass!, + member.name, + setter: member.isSetter, + ) : null; var needsSignature = memberOverride == null || @@ -1736,8 +1930,9 @@ var memberName = _declareMemberName(member); if (!member.isAccessor) { var immediateTarget = js.string(fullyResolvedTargetLabel(member)); - methodsImmediateTarget - .add(js_ast.Property(memberName, immediateTarget)); + methodsImmediateTarget.add( + js_ast.Property(memberName, immediateTarget), + ); } if (needsSignature) { @@ -1748,9 +1943,11 @@ // library internals and should not be included in the accessible // signatures. if (c == _jsArrayClass && name == 'arrayRti') continue; - type = _emitType(member.isGetter - ? reifiedType.returnType - : reifiedType.positionalParameters[0]); + type = _emitType( + member.isGetter + ? reifiedType.returnType + : reifiedType.positionalParameters[0], + ); } else { type = _emitType(reifiedType); if (!member.isStatic && reifiedType.typeParameters.isNotEmpty) { @@ -1760,7 +1957,7 @@ // use at runtime. var defaultTypeArgs = js_ast.ArrayInitializer([ for (var parameter in reifiedType.typeParameters) - _emitType(parameter.defaultType) + _emitType(parameter.defaultType), ]); var typeResolver = js_ast.ArrowFun([_rtiParam], defaultTypeArgs); var property = js_ast.Property(memberName, typeResolver); @@ -1772,7 +1969,9 @@ // TODO(52867): Cleanup default type argument duplication. if (extMethods.contains(name) || extAccessors.contains(name)) { var property = js_ast.Property( - _declareMemberName(member, useExtension: true), typeResolver); + _declareMemberName(member, useExtension: true), + typeResolver, + ); instanceMethodsDefaultTypeArgs.add(property); } } @@ -1786,7 +1985,9 @@ // TODO(52867): Cleanup signature duplication. var typeResolver = js_ast.ArrowFun([_rtiParam], type); var property = js_ast.Property( - _declareMemberName(member, useExtension: true), typeResolver); + _declareMemberName(member, useExtension: true), + typeResolver, + ); signatures.add(property); } } @@ -1802,8 +2003,12 @@ emitSignature('Setter', instanceSetters); emitSignature('StaticGetter', staticGetters); emitSignature('StaticSetter', staticSetters); - body.add(_runtimeStatement('setLibraryUri(#, #)', - [className, _cacheUri(_jsLibraryDebuggerName(c.enclosingLibrary))])); + body.add( + _runtimeStatement('setLibraryUri(#, #)', [ + className, + _cacheUri(_jsLibraryDebuggerName(c.enclosingLibrary)), + ]), + ); var instanceFields = <js_ast.Property>[]; var staticFields = <js_ast.Property>[]; @@ -1841,36 +2046,48 @@ var fComputed = f.computeThisFunctionType(Nullability.nonNullable); var fComputedNamedByName = { for (NamedType namedParameter in fComputed.namedParameters) - namedParameter.name: namedParameter + namedParameter.name: namedParameter, }; DartType reifyParameter( - VariableDeclaration parameter, DartType fComputedParameter) => + VariableDeclaration parameter, + DartType fComputedParameter, + ) => isCovariantParameter(parameter) ? _coreTypes.objectNullableRawType : fComputedParameter; NamedType reifyNamedParameter( - VariableDeclaration parameter, NamedType fComputedNamedParameter) { + VariableDeclaration parameter, + NamedType fComputedNamedParameter, + ) { assert(parameter.name == fComputedNamedParameter.name); - return NamedType(parameter.name!, - reifyParameter(parameter, fComputedNamedParameter.type)); + return NamedType( + parameter.name!, + reifyParameter(parameter, fComputedNamedParameter.type), + ); } // TODO(jmesserly): do covariant type parameter bounds also need to be // reified as `Object`? result = FunctionType( - List<DartType>.generate( - f.positionalParameters.length, - (index) => reifyParameter(f.positionalParameters[index], - fComputed.positionalParameters[index])), - f.returnType, - Nullability.nonNullable, - namedParameters: List<NamedType>.generate( - f.namedParameters.length, - (index) => reifyNamedParameter(f.namedParameters[index], - fComputedNamedByName[f.namedParameters[index].name]!)) - ..sort(), - typeParameters: fComputed.typeParameters, - requiredParameterCount: f.requiredParameterCount); + List<DartType>.generate( + f.positionalParameters.length, + (index) => reifyParameter( + f.positionalParameters[index], + fComputed.positionalParameters[index], + ), + ), + f.returnType, + Nullability.nonNullable, + namedParameters: List<NamedType>.generate( + f.namedParameters.length, + (index) => reifyNamedParameter( + f.namedParameters[index], + fComputedNamedByName[f.namedParameters[index].name]!, + ), + )..sort(), + typeParameters: fComputed.typeParameters, + requiredParameterCount: f.requiredParameterCount, + ); } return _typeFromClass(result, member.enclosingClass!, fromClass) as FunctionType; @@ -1879,26 +2096,31 @@ DartType _typeFromClass(DartType type, Class superclass, Class subclass) { if (identical(superclass, subclass)) return type; return Substitution.fromSupertype( - _hierarchy.getClassAsInstanceOf(subclass, superclass)!) - .substituteType(type); + _hierarchy.getClassAsInstanceOf(subclass, superclass)!, + ).substituteType(type); } js_ast.Expression _emitConstructor( - Constructor node, List<Field> fields, js_ast.Expression className) { + Constructor node, + List<Field> fields, + js_ast.Expression className, + ) { var savedUri = _currentUri; _currentUri = node.fileUri; _staticTypeContext.enterMember(node); var savedTypeEnvironment = _currentTypeEnvironment; - _currentTypeEnvironment = - ClassTypeEnvironment(node.enclosingClass.typeParameters); + _currentTypeEnvironment = ClassTypeEnvironment( + node.enclosingClass.typeParameters, + ); var params = <js_ast.Parameter>[]; // Generic class constructors accept their RTI as their first argument. params.addAll(_emitParameters(node.function)); var body = _withCurrentFunction( - node.function, - () => _superDisallowed( - () => _emitConstructorBody(node, fields, className))); + node.function, + () => + _superDisallowed(() => _emitConstructorBody(node, fields, className)), + ); var end = _nodeEnd(node.fileEndOffset); _currentUri = savedUri; @@ -1907,7 +2129,7 @@ var constructor = js_ast.Fun([ if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam, - ...params + ...params, ], js_ast.Block(body)) ..sourceInformation = end; @@ -1936,12 +2158,14 @@ // Only set the rti if there isn't one already. This avoids superclasses // overwriting the value already set by a subclass. var rtiProperty = _propertyName(js_ast.FixedNames.rtiName); - body.add(js.statement('this.# = this.# || # || #', [ - rtiProperty, - rtiProperty, - _rtiParam, - _runtimeCall('getReifiedType(this)') - ])); + body.add( + js.statement('this.# = this.# || # || #', [ + rtiProperty, + rtiProperty, + _rtiParam, + _runtimeCall('getReifiedType(this)'), + ]), + ); } // Redirecting constructors are not allowed to have conventional @@ -2027,7 +2251,9 @@ } js_ast.Statement _emitRedirectingConstructor( - List<Initializer> initializers, js_ast.Expression className) { + List<Initializer> initializers, + js_ast.Expression className, + ) { var jsInitializers = <js_ast.Statement>[]; for (var init in initializers) { if (init is LocalInitializer) { @@ -2045,8 +2271,8 @@ _constructorName(init.target.name.text), [ if (rtiParam != null) rtiParam, - ..._emitArgumentList(init.arguments, types: false) - ] + ..._emitArgumentList(init.arguments, types: false), + ], ]); jsInitializers.add(initializer); } @@ -2055,7 +2281,10 @@ } js_ast.Statement? _emitSuperConstructorCallIfNeeded( - Class c, js_ast.Expression className, SuperInitializer? superInit) { + Class c, + js_ast.Expression className, + SuperInitializer? superInit, + ) { if (c == _coreTypes.objectClass) return null; Constructor ctor; @@ -2074,7 +2303,7 @@ : null; args = [ if (rti != null) rti, - ..._emitArgumentList(superInit.arguments, types: true) + ..._emitArgumentList(superInit.arguments, types: true), ]; _currentTypeEnvironment = savedTypeEnvironment; @@ -2088,12 +2317,16 @@ return _emitSuperConstructorCall(ctor, className, ctor.name.text, args); } - js_ast.Statement _emitSuperConstructorCall(Constructor constructor, - js_ast.Expression className, String name, List<js_ast.Expression> args) { + js_ast.Statement _emitSuperConstructorCall( + Constructor constructor, + js_ast.Expression className, + String name, + List<js_ast.Expression> args, + ) { return js.statement('#.#.call(this, #);', [ _emitJSObjectGetPrototypeOf(className, fullyQualifiedName: true), _constructorName(name), - args + args, ]); } @@ -2137,10 +2370,14 @@ ? _declareMemberName(f) : _getSymbol(virtualField); var jsInit = _visitInitializer(initializer, f.annotations); - body.add(jsInit - .toAssignExpression(js.call('this.#', [access]) - ..sourceInformation = _nodeStart(hoverInfo)) - .toStatement()); + body.add( + jsInit + .toAssignExpression( + js.call('this.#', [access]) + ..sourceInformation = _nodeStart(hoverInfo), + ) + .toStatement(), + ); } for (var f in fields) { @@ -2173,7 +2410,9 @@ } js_ast.Expression _visitInitializer( - Expression? init, List<Expression> annotations) { + Expression? init, + List<Expression> annotations, + ) { // explicitly initialize to null, to avoid getting `undefined`. // TODO(jmesserly): do this only for vars that aren't definitely assigned. if (init == null) return js_ast.LiteralNull(); @@ -2199,8 +2438,12 @@ mixin.constructors.every((c) => c.isExternal); } - js_ast.Statement _addConstructorToClass(Class c, js_ast.Expression className, - js_ast.LiteralString name, js_ast.Expression jsCtor) { + js_ast.Statement _addConstructorToClass( + Class c, + js_ast.Expression className, + js_ast.LiteralString name, + js_ast.Expression jsCtor, + ) { jsCtor = _defineValueOnClass(c, className, name, jsCtor); return js.statement('#.prototype = #.prototype;', [jsCtor, className]); } @@ -2233,14 +2476,22 @@ if (c == _coreTypes.objectClass) { // Dart does not use ES6 constructors. // Add an error to catch any invalid usage. - jsMethods.add(js_ast.Method( + jsMethods.add( + js_ast.Method( _propertyName('constructor'), - js.fun(r'''function() { + js.fun( + r'''function() { throw Error("use `new " + # + ".new(...)` to create a Dart object"); - }''', [ - _runtimeCall('typeName(#)', [_runtimeCall('getReifiedType(this)')]) - ]))); + }''', + [ + _runtimeCall('typeName(#)', [ + _runtimeCall('getReifiedType(this)'), + ]), + ], + ), + ), + ); } else if (c == _jsArrayClass) { // Provide access to the Array constructor property, so it works like // other native types (rather than calling the Dart Object "constructor" @@ -2248,8 +2499,12 @@ // // This will become obsolete when // https://github.com/dart-lang/sdk/issues/31003 is addressed. - jsMethods.add(js_ast.Method( - _propertyName('constructor'), js.fun(r'function() { return []; }'))); + jsMethods.add( + js_ast.Method( + _propertyName('constructor'), + js.fun(r'function() { return []; }'), + ), + ); } var staticFieldNames = <Name>{}; @@ -2367,16 +2622,23 @@ fn = _emitNativeFunctionBody(member); } else { fn = _withMethodDeclarationContext( - member, - () => _emitFunction(member.function, member.name.text, - functionBody: _toSourceLocation(member.fileOffset), - functionEnd: _toSourceLocation(member.fileEndOffset))); + member, + () => _emitFunction( + member.function, + member.name.text, + functionBody: _toSourceLocation(member.fileOffset), + functionEnd: _toSourceLocation(member.fileEndOffset), + ), + ); } - var method = js_ast.Method(_declareMemberName(member), fn, - isGetter: member.isGetter, - isSetter: member.isSetter, - isStatic: member.isStatic); + var method = js_ast.Method( + _declareMemberName(member), + fn, + isGetter: member.isGetter, + isSetter: member.isSetter, + isStatic: member.isStatic, + ); if (isTearOffLowering(member)) { // Remove all source information from static methods introduced by the @@ -2401,7 +2663,9 @@ } else if (node.isSetter) { var params = _emitParameters(node.function); return js_ast.Fun( - params, js.block('{ this.# = #; }', [name, params.last])); + params, + js.block('{ this.# = #; }', [name, params.last]), + ); } else { var returnValue = js('this.#.apply(this, args)', [name]); if (_isNullCheckableNative(node)) { @@ -2437,26 +2701,37 @@ if (superMember is Field && isCovariantField(superMember) || superMember is Procedure && isCovariantParameter( - superMemberFunction!.positionalParameters[0])) { + superMemberFunction!.positionalParameters[0], + )) { return const []; } - var setterType = - substituteType(superMember.superSetterType).extensionTypeErasure; + var setterType = substituteType( + superMember.superSetterType, + ).extensionTypeErasure; if (_types.isTop(setterType)) return const []; return [ js_ast.Method( + name, + js.fun('function(x) { return super.# = #; }', [ name, - js.fun('function(x) { return super.# = #; }', - [name, _emitCast(_emitIdentifier('x'), setterType)]), - isSetter: true), - js_ast.Method(name, js.fun('function() { return super.#; }', [name]), - isGetter: true) + _emitCast(_emitIdentifier('x'), setterType), + ]), + isSetter: true, + ), + js_ast.Method( + name, + js.fun('function() { return super.#; }', [name]), + isGetter: true, + ), ]; } assert(!member.isAccessor); - var superMethodType = substituteType(superMemberFunction! - .computeThisFunctionType(Nullability.nonNullable)) as FunctionType; + var superMethodType = substituteType( + superMemberFunction!.computeThisFunctionType( + Nullability.nonNullable, + ), + ) as FunctionType; var function = member.function; var body = <js_ast.Statement>[]; @@ -2484,16 +2759,24 @@ var namedParameters = function.namedParameters; for (var param in namedParameters) { if (isCovariantParameter(param) && - !isCovariantParameter(superMemberFunction.namedParameters - .firstWhere((n) => n.name == param.name))) { + !isCovariantParameter( + superMemberFunction.namedParameters.firstWhere( + (n) => n.name == param.name, + ), + )) { var name = _propertyName(param.name!); - var paramType = superMethodType.namedParameters - .firstWhere((n) => n.name == param.name); - body.add(js.statement('if (#) #;', [ - _namedArgumentProbe(name), - _emitCast( - js_ast.PropertyAccess(_namedArgumentTemp, name), paramType.type) - ])); + var paramType = superMethodType.namedParameters.firstWhere( + (n) => n.name == param.name, + ); + body.add( + js.statement('if (#) #;', [ + _namedArgumentProbe(name), + _emitCast( + js_ast.PropertyAccess(_namedArgumentTemp, name), + paramType.type, + ), + ]), + ); } } @@ -2522,27 +2805,26 @@ final savedTypeEnvironment = _currentTypeEnvironment; _currentTypeEnvironment = RtiTypeEnvironment([ ...function.typeParameters, - ..._currentTypeEnvironment.classTypeParameters + ..._currentTypeEnvironment.classTypeParameters, ]); - var jsBody = js_ast.Block(_withCurrentFunction(function, () { - var block = _emitArgumentInitializers(function, name); - block.add(_emitFunctionScopedBody(function)); - return block; - })); + var jsBody = js_ast.Block( + _withCurrentFunction(function, () { + var block = _emitArgumentInitializers(function, name); + block.add(_emitFunctionScopedBody(function)); + return block; + }), + ); var jsName = _constructorName(name); memberNames[node] = jsName.valueWithoutQuotes; // Generic class constructors accept their RTI as their first argument. var method = js_ast.Method( jsName, - js_ast.Fun( - [ - if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam, - ..._emitParameters(function) - ], - jsBody, - ), + js_ast.Fun([ + if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam, + ..._emitParameters(function), + ], jsBody), isStatic: true, )..sourceInformation = _nodeEnd(node.fileEndOffset); _currentTypeEnvironment = savedTypeEnvironment; @@ -2576,12 +2858,17 @@ : [ js_ast.This(), virtualFieldSymbol, - if (isCovariantField(field)) _emitCast(value, field.type) else value + if (isCovariantField(field)) + _emitCast(value, field.type) + else + value, ]; body.add(js.call('#[#] = #', args).toStatement()); - var jsSetter = js_ast.Method(name, js_ast.Fun([value], js_ast.Block(body)), - isSetter: true) - ..sourceInformation = _nodeStart(field); + var jsSetter = js_ast.Method( + name, + js_ast.Fun([value], js_ast.Block(body)), + isSetter: true, + )..sourceInformation = _nodeStart(field); return [jsGetter, jsSetter]; } @@ -2621,8 +2908,11 @@ /// This is needed because in ES6, if you only override a getter /// (alternatively, a setter), then there is an implicit override of the /// setter (alternatively, the getter) that does nothing. - js_ast.Method? _emitSuperAccessorWrapper(Procedure member, - Map<String, Procedure> getters, Map<String, Procedure> setters) { + js_ast.Method? _emitSuperAccessorWrapper( + Procedure member, + Map<String, Procedure> getters, + Map<String, Procedure> setters, + ) { if (member.isAbstract) return null; var name = member.name.text; @@ -2664,8 +2954,10 @@ var parent = _hierarchy.getDispatchTarget(superclass, Name('iterator')); if (parent != null) return null; - var parentIterable = - _hierarchy.getClassAsInstanceOf(superclass, _coreTypes.iterableClass); + var parentIterable = _hierarchy.getClassAsInstanceOf( + superclass, + _coreTypes.iterableClass, + ); if (parentIterable != null) return null; if (c.enclosingLibrary.importUri.isScheme('dart') && @@ -2676,24 +2968,33 @@ // Otherwise, emit the adapter method, which wraps the Dart iterator in // an ES6 iterator. return js_ast.Method( - js.call('Symbol.iterator'), - // TODO(nshahan) Don't access values in `runtimeModule` outside of - // `runtimeCall`. - js.call('function() { return new #.JsIterator(this.#); }', [ - _runtimeModule, - _emitMemberName('iterator', memberClass: _coreTypes.iterableClass) - ]) as js_ast.Fun); + js.call('Symbol.iterator'), + // TODO(nshahan) Don't access values in `runtimeModule` outside of + // `runtimeCall`. + js.call('function() { return new #.JsIterator(this.#); }', [ + _runtimeModule, + _emitMemberName('iterator', memberClass: _coreTypes.iterableClass), + ]) as js_ast.Fun, + ); } void _registerExtensionType( - Class c, String jsPeerName, List<js_ast.Statement> body) { + Class c, + String jsPeerName, + List<js_ast.Statement> body, + ) { var className = _emitTopLevelName(c); if (_typeRep.isPrimitive(_coreTypes.nonNullableRawType(c))) { - body.add(_runtimeStatement( - 'definePrimitiveHashCode(#.prototype)', [className])); + body.add( + _runtimeStatement('definePrimitiveHashCode(#.prototype)', [className]), + ); } - body.add(_runtimeStatement( - 'registerExtension(#, #)', [js.string(jsPeerName), className])); + body.add( + _runtimeStatement('registerExtension(#, #)', [ + js.string(jsPeerName), + className, + ]), + ); } void _emitTopLevelFields(List<Field> fields) { @@ -2725,10 +3026,12 @@ _emitClass(type.classNode); } _currentUri = field.fileUri; - _moduleItems.add(js.statement('# = #;', [ - _emitTopLevelName(field), - _visitInitializer(init, field.annotations) - ])); + _moduleItems.add( + js.statement('# = #;', [ + _emitTopLevelName(field), + _visitInitializer(init, field.annotations), + ]), + ); } else { lazyFields.add(field); } @@ -2740,8 +3043,13 @@ } if (fields.isEmpty) return; - _moduleItems.add(_emitLazyMembers( - _emitLibraryName(_currentLibrary!), fields, _emitTopLevelMemberName)); + _moduleItems.add( + _emitLazyMembers( + _emitLibraryName(_currentLibrary!), + fields, + _emitTopLevelMemberName, + ), + ); } js_ast.Statement _emitLazyMembers( @@ -2759,29 +3067,44 @@ memberNames[member] = access.valueWithoutQuotes; if (member is Field) { - accessors.add(js_ast.Method(access, _emitStaticFieldInitializer(member), - isGetter: true) - ..sourceInformation = _hoverComment( + accessors.add( + js_ast.Method( + access, + _emitStaticFieldInitializer(member), + isGetter: true, + )..sourceInformation = _hoverComment( js_ast.PropertyAccess(objExpr, access), member.fileOffset, - member.name.text.length)); + member.name.text.length, + ), + ); if (!member.isFinal && !member.isConst) { // A dummy setter is still required to indicate writeable. - accessors.add(js_ast.Method(access, + accessors.add( + js_ast.Method( + access, js_ast.Fun([_emitIdentifier('value')], js_ast.Block(const [])), - isSetter: true)); + isSetter: true, + ), + ); } } else if (member is Procedure) { - accessors.add(js_ast.Method( - access, _emitFunction(member.function, member.name.text), - isGetter: member.isGetter, isSetter: member.isSetter) - ..sourceInformation = _hoverComment( + accessors.add( + js_ast.Method( + access, + _emitFunction(member.function, member.name.text), + isGetter: member.isGetter, + isSetter: member.isSetter, + )..sourceInformation = _hoverComment( js_ast.PropertyAccess(objExpr, access), member.fileOffset, - member.name.text.length)); + member.name.text.length, + ), + ); } else { throw UnsupportedError( - 'Unsupported lazy member type ${member.runtimeType}: $member'); + 'Unsupported lazy member type ${member.runtimeType}: $member', + ); } _staticTypeContext.leaveMember(member); } @@ -2791,15 +3114,23 @@ } js_ast.Fun _emitStaticFieldInitializer(Field field) { - return js_ast.Fun([], js_ast.Block(_withLetScope(() { - return [ - js_ast.Return(_visitInitializer(field.initializer, field.annotations)) - ]; - }))); + return js_ast.Fun( + [], + js_ast.Block( + _withLetScope(() { + return [ + js_ast.Return( + _visitInitializer(field.initializer, field.annotations), + ), + ]; + }), + ), + ); } List<js_ast.Statement> _withLetScope( - List<js_ast.Statement> Function() visitBody) { + List<js_ast.Statement> Function() visitBody, + ) { var savedLetVariables = _letVariables; _letVariables = []; @@ -2824,10 +3155,12 @@ var c = m.enclosingClass; var actualUseExtension = useExtension || (c != null && _extensionTypes.isNativeClass(c)); - return _emitMemberName(m.name.text, - isStatic: m is Field ? m.isStatic : (m as Procedure).isStatic, - useExtension: actualUseExtension, - member: m); + return _emitMemberName( + m.name.text, + isStatic: m is Field ? m.isStatic : (m as Procedure).isStatic, + useExtension: actualUseExtension, + member: m, + ); } /// This handles member renaming for private names and operators. @@ -2870,11 +3203,13 @@ /// Equality is a bit special, it is generated via the Dart `equals` runtime /// helper, that checks for null. The user defined method is called '=='. /// - js_ast.Expression _emitMemberName(String name, - {bool isStatic = false, - bool? useExtension, - Member? member, - Class? memberClass}) { + js_ast.Expression _emitMemberName( + String name, { + bool isStatic = false, + bool? useExtension, + Member? member, + Class? memberClass, + }) { // Static members skip the rename steps and may require JS interop renames. if (isStatic) { var memberName = _emitStaticMemberName(name, member); @@ -2913,8 +3248,8 @@ _currentLibrary!; if (member != null) { // TODO(40273) Move this name collection to another location. - // We really only want to collect member names when the member is created, - // not called. + // We really only want to collect member names when the member is + // created, not called. // Wrap the name as a symbol here so it matches what you would find at // runtime when you get all properties and symbols from an instance. memberNames[member] = 'Symbol($name)'; @@ -2983,10 +3318,11 @@ var map = _forwardingCache.putIfAbsent(c, () => {}); return map.putIfAbsent( - name, - () => - _hierarchy.getDispatchTarget(c, Name(name)) ?? - _hierarchy.getDispatchTarget(c, Name(name), setter: true)); + name, + () => + _hierarchy.getDispatchTarget(c, Name(name)) ?? + _hierarchy.getDispatchTarget(c, Name(name), setter: true), + ); } js_ast.LiteralString _emitStaticMemberName(String name, [NamedNode? member]) { @@ -3039,7 +3375,9 @@ (type is InterfaceType && type.classNode == _coreTypes.functionClass)) { if (!isAllowInterop(f)) { return StaticInvocation( - _assertInteropMethod, Arguments([f], types: [type])); + _assertInteropMethod, + Arguments([f], types: [type]), + ); } } return f; @@ -3050,30 +3388,37 @@ if (!usesJSInterop(n)) return null; if (n is Member && !n.isExternal) return null; var name = _annotationName(n, isJSInteropAnnotation) ?? getTopLevelName(n); - assert(!name.contains('.'), - 'JS interop checker rejects dotted names on static class members'); + assert( + !name.contains('.'), + 'JS interop checker rejects dotted names on static class members', + ); return js.escapedString(name, "'"); } /// Emit the top-level name associated with [n], which should not be an /// external interop member. - js_ast.PropertyAccess _emitTopLevelNameNoExternalInterop(NamedNode n, - {String suffix = ''}) { + js_ast.PropertyAccess _emitTopLevelNameNoExternalInterop( + NamedNode n, { + String suffix = '', + }) { // Some native tests use top-level native methods. var isTopLevelNative = n is Member && isNative(n); return js_ast.PropertyAccess( - isTopLevelNative - ? _runtimeCall('global.self') - : _emitLibraryName(getLibrary(n)), - _emitTopLevelMemberName(n, suffix: suffix)); + isTopLevelNative + ? _runtimeCall('global.self') + : _emitLibraryName(getLibrary(n)), + _emitTopLevelMemberName(n, suffix: suffix), + ); } /// Emits the member name portion of a top-level member. /// /// NOTE: usually you should use [_emitTopLevelName] instead of this. This /// function does not handle JS interop. - js_ast.LiteralString _emitTopLevelMemberName(NamedNode n, - {String suffix = ''}) { + js_ast.LiteralString _emitTopLevelMemberName( + NamedNode n, { + String suffix = '', + }) { var name = _jsExportName(n) ?? getTopLevelName(n); return _propertyName(name + suffix); } @@ -3144,15 +3489,18 @@ js_ast.PropertyAccess? access; for (var part in parts) { access = js_ast.PropertyAccess( - access ?? _runtimeCall('global'), js.escapedString(part, "'")); + access ?? _runtimeCall('global'), + js.escapedString(part, "'"), + ); } return access!; } void _emitLibraryProcedures(Library library) { var procedures = library.procedures - .where((p) => - !p.isExternal && !p.isAbstract && !_isStaticInteropTearOff(p)) + .where( + (p) => !p.isExternal && !p.isAbstract && !_isStaticInteropTearOff(p), + ) .toList(); for (var p in procedures) { if (!p.isAccessor) { @@ -3163,12 +3511,13 @@ // can tag them during the delta diff phase. if (p.isStatic && _reifyTearoff(p) && !p.isExternal) { var nameExpr = _emitTopLevelName(p); - _moduleItems.add(_emitFunctionTagged( - nameExpr, - p.function - .computeThisFunctionType(p.enclosingLibrary.nonNullable), - asLazy: true) - .toStatement()); + _moduleItems.add( + _emitFunctionTagged( + nameExpr, + p.function.computeThisFunctionType(p.enclosingLibrary.nonNullable), + asLazy: true, + ).toStatement(), + ); } } _emitLibraryAccessors(procedures.where((p) => p.isAccessor).toList()); @@ -3198,14 +3547,18 @@ final factoryName = extractConstructorNameFromTearOff(p.name); if (factoryName != null) { if (factoryName.isEmpty && - enclosingClass.constructors.any((constructor) => - constructor.isSynthetic && constructor.name.text.isEmpty)) { + enclosingClass.constructors.any( + (constructor) => + constructor.isSynthetic && constructor.name.text.isEmpty, + )) { return true; } - if (enclosingClass.procedures.any((procedure) => - procedure.isFactory && - procedure.isExternal && - procedure.name.text == factoryName)) { + if (enclosingClass.procedures.any( + (procedure) => + procedure.isFactory && + procedure.isExternal && + procedure.name.text == factoryName, + )) { return true; } } @@ -3215,10 +3568,12 @@ void _emitLibraryAccessors(Iterable<Procedure> accessors) { if (accessors.isEmpty) return; - _moduleItems.add(_runtimeStatement('copyProperties(#, { # })', [ - _emitLibraryName(_currentLibrary!), - accessors.map(_emitLibraryAccessor).toList() - ])); + _moduleItems.add( + _runtimeStatement('copyProperties(#, { # })', [ + _emitLibraryName(_currentLibrary!), + accessors.map(_emitLibraryAccessor).toList(), + ]), + ); } js_ast.Method _emitLibraryAccessor(Procedure node) { @@ -3229,9 +3584,11 @@ var name = node.name.text; memberNames[node] = name; var result = js_ast.Method( - _propertyName(name), _emitFunction(node.function, name), - isGetter: node.isGetter, isSetter: node.isSetter) - ..sourceInformation = _nodeEnd(node.fileEndOffset); + _propertyName(name), + _emitFunction(node.function, name), + isGetter: node.isGetter, + isSetter: node.isSetter, + )..sourceInformation = _nodeEnd(node.fileEndOffset); _currentUri = savedUri; _staticTypeContext.leaveMember(node); @@ -3244,10 +3601,12 @@ _currentUri = p.fileUri; var body = <js_ast.Statement>[]; - var fn = _emitFunction(p.function, p.name.text, - functionBody: _toSourceLocation(p.fileOffset), - functionEnd: _toSourceLocation(p.fileEndOffset)) - ..sourceInformation = _nodeEnd(p.fileEndOffset); + var fn = _emitFunction( + p.function, + p.name.text, + functionBody: _toSourceLocation(p.fileOffset), + functionEnd: _toSourceLocation(p.fileEndOffset), + )..sourceInformation = _nodeEnd(p.fileEndOffset); if (_currentLibrary!.importUri.isScheme('dart') && _isInlineJSFunction(p.function.body)) { @@ -3258,8 +3617,9 @@ var jsName = _safeFunctionNameForSafari(p.name.text, fn); var functionName = _emitScopedId(jsName); procedureIdentifiers[p] = functionName; - body.add(js.statement( - '# = #', [nameExpr, js_ast.NamedFunction(functionName, fn)])); + body.add( + js.statement('# = #', [nameExpr, js_ast.NamedFunction(functionName, fn)]), + ); _currentUri = savedUri; _staticTypeContext.leaveMember(p); @@ -3270,8 +3630,10 @@ if (p.function.requiredParameterCount > 0) { // TODO(sigmund): this error should be caught by a kernel checker that // runs prior to DDC. - throw StateError('Entrypoint ${p.name.text} must accept being called ' - 'with 0 arguments.'); + throw StateError( + 'Entrypoint ${p.name.text} must accept being called ' + 'with 0 arguments.', + ); } else { _dynamicEntrypoint = p; } @@ -3298,7 +3660,9 @@ /// name overlap with the parameter names as well. This rename works around /// such bug (dartbug.com/43520). static String _safeFunctionNameForSafari( - String candidateName, js_ast.Fun fn) { + String candidateName, + js_ast.Fun fn, + ) { if (fn.params.any((p) => p is js_ast.DestructuredVariable)) { while (fn.params.any((a) => a.parameterName == candidateName)) { candidateName = '$candidateName\$'; @@ -3307,11 +3671,15 @@ return candidateName; } - js_ast.Expression _emitFunctionTagged(js_ast.Expression fn, FunctionType type, - {bool asLazy = false}) { + js_ast.Expression _emitFunctionTagged( + js_ast.Expression fn, + FunctionType type, { + bool asLazy = false, + }) { var typeRep = _emitType( - // Avoid tagging a closure as Function? or Function* - type.withDeclaredNullability(Nullability.nonNullable)); + // Avoid tagging a closure as Function? or Function* + type.withDeclaredNullability(Nullability.nonNullable), + ); if (type.typeParameters.isEmpty) { return asLazy ? _runtimeCall('lazyFn(#, () => #)', [fn, typeRep]) @@ -3319,15 +3687,23 @@ } else { var typeParameterDefaults = [ for (var parameter in type.typeParameters) - _emitType(parameter.defaultType) + _emitType(parameter.defaultType), ]; - var defaultInstantiatedBounds = - _emitConstList(const DynamicType(), typeParameterDefaults); + var defaultInstantiatedBounds = _emitConstList( + const DynamicType(), + typeParameterDefaults, + ); return asLazy - ? _runtimeCall('lazyGFn(#, () => #, () => #)', - [fn, typeRep, defaultInstantiatedBounds]) - : _runtimeCall( - 'gFn(#, #, #)', [fn, typeRep, defaultInstantiatedBounds]); + ? _runtimeCall('lazyGFn(#, () => #, () => #)', [ + fn, + typeRep, + defaultInstantiatedBounds, + ]) + : _runtimeCall('gFn(#, #, #)', [ + fn, + typeRep, + defaultInstantiatedBounds, + ]); } } @@ -3340,16 +3716,22 @@ /// in most cases except for uses in non-external JS interop factories. /// Note: This only applies to the old style package:js interop and isn't /// necessary for any forms of static JS interop. - js_ast.Expression _emitType(DartType type, - {bool emitJSInteropGenericClassTypeParametersAsAny = true}) { + js_ast.Expression _emitType( + DartType type, { + bool emitJSInteropGenericClassTypeParametersAsAny = true, + }) { /// Returns an expression that evaluates a type [recipe] within the type /// [environment]. /// /// At runtime the expression will evaluate to an rti object. js_ast.Expression emitRtiEval( - js_ast.Expression environment, String recipe) => - js.call('#.#("$recipe")', - [environment, _emitMemberName('_eval', memberClass: _rtiClass)]); + js_ast.Expression environment, + String recipe, + ) => + js.call('#.#("$recipe")', [ + environment, + _emitMemberName('_eval', memberClass: _rtiClass), + ]); /// Returns an expression that binds a type [parameter] within the type /// [environment]. @@ -3357,29 +3739,34 @@ /// At runtime the expression will evaluate to an rti object that has been /// extended to include the provided [parameter]. js_ast.Expression emitRtiBind( - js_ast.Expression environment, TypeParameter parameter) { + js_ast.Expression environment, + TypeParameter parameter, + ) { return js.call('#.#(#)', [ environment, _emitMemberName('_bind', memberClass: _rtiClass), - _emitTypeParameter(parameter) + _emitTypeParameter(parameter), ]); } /// Returns an expression that evaluates a type [recipe] in a type /// [environment] resulting in an rti object. js_ast.Expression evalInEnvironment( - DDCTypeEnvironment environment, String recipe) { + DDCTypeEnvironment environment, + String recipe, + ) { switch (environment) { case EmptyTypeEnvironment(): - // Cache ground types in the type table for fast lookup. The table will - // lazily lookup the RTI object on first access and then replace the - // lazy getter with the initialized RTI object. + // Cache ground types in the type table for fast lookup. The table + // will lazily lookup the RTI object on first access and then replace + // the lazy getter with the initialized RTI object. return _typeTable.nameType( - type, - js.call('#._Universe.eval(#, "$recipe", true)', [ - _emitLibraryName(_rtiLibrary), - _runtimeCall('typeUniverse'), - ])); + type, + js.call('#._Universe.eval(#, "$recipe", true)', [ + _emitLibraryName(_rtiLibrary), + _runtimeCall('typeUniverse'), + ]), + ); case BindingTypeEnvironment(): js_ast.Expression env; if (environment.isSingleTypeParameter) { @@ -3391,8 +3778,10 @@ } else { var environmentTypes = environment.functionTypeParameters; // Create a dummy interface type to "hold" type arguments. - env = - emitRtiEval(_emitTypeParameter(environmentTypes.first), '@<0>'); + env = emitRtiEval( + _emitTypeParameter(environmentTypes.first), + '@<0>', + ); // Bind remaining type arguments. for (var i = 1; i < environmentTypes.length; i++) { env = emitRtiBind(env, environmentTypes[i]); @@ -3407,34 +3796,43 @@ case ClassTypeEnvironment(): // Class type environments are already constructed and attached to the // instance of a generic class. - var env = - js.call('#.instanceType(this)', [_emitLibraryName(_rtiLibrary)]); + var env = js.call('#.instanceType(this)', [ + _emitLibraryName(_rtiLibrary), + ]); return emitRtiEval(env, recipe); case ExtendedTypeEnvironment(): // Class type environments are already constructed and attached to the // instance of a generic class, but function type parameters need to // be bound. - var env = - js.call('#.instanceType(this)', [_emitLibraryName(_rtiLibrary)]); + var env = js.call('#.instanceType(this)', [ + _emitLibraryName(_rtiLibrary), + ]); // Bind extra type parameters. for (var parameter in environment.functionTypeParameters) { env = emitRtiBind(env, parameter); } return emitRtiEval(env, recipe); } - _typeCompilationError(type, - 'Unexpected DDCTypeEnvironment type (${environment.runtimeType}).'); + _typeCompilationError( + type, + 'Unexpected DDCTypeEnvironment type (${environment.runtimeType}).', + ); } - var normalizedType = - _futureOrNormalizer.normalize(type.extensionTypeErasure); + var normalizedType = _futureOrNormalizer.normalize( + type.extensionTypeErasure, + ); try { var result = _typeRecipeGenerator.recipeInEnvironment( - normalizedType, _currentTypeEnvironment, - emitJSInteropGenericClassTypeParametersAsAny: - emitJSInteropGenericClassTypeParametersAsAny); - var typeRep = - evalInEnvironment(result.requiredEnvironment, result.recipe); + normalizedType, + _currentTypeEnvironment, + emitJSInteropGenericClassTypeParametersAsAny: + emitJSInteropGenericClassTypeParametersAsAny, + ); + var typeRep = evalInEnvironment( + result.requiredEnvironment, + result.recipe, + ); return typeRep; } on UnsupportedError catch (e) { _typeCompilationError(normalizedType, e.message ?? 'Unknown Error'); @@ -3443,8 +3841,9 @@ js_ast.Expression _emitInvalidNode(Node node, [String message = '']) { if (message.isNotEmpty) message += ' '; - return _runtimeCall('throwUnimplementedError(#)', - [js.escapedString('node <${node.runtimeType}> $message`$node`')]); + return _runtimeCall('throwUnimplementedError(#)', [ + js.escapedString('node <${node.runtimeType}> $message`$node`'), + ]); } /// Emits a reference to the class described by [type]. @@ -3469,8 +3868,10 @@ } Never _typeCompilationError(DartType type, String description) => - throw UnsupportedError('$description Encountered while compiling ' - '${_currentLibrary!.fileUri}, which contains the type: $type.'); + throw UnsupportedError( + '$description Encountered while compiling ' + '${_currentLibrary!.fileUri}, which contains the type: $type.', + ); bool get _emittingClassExtends => _currentClass != null && identical(_currentClass, _classEmittingExtends); @@ -3488,7 +3889,9 @@ // If it's non-external but belongs to an interop class, we want the class // reference we defined in `_emitJSInteropClassNonExternalMembers`. return js_ast.PropertyAccess( - _emitClassRef(type), _constructorName(c.name.text)); + _emitClassRef(type), + _constructorName(c.name.text), + ); } /// Emits an expression that lets you access statics on [c] from code. @@ -3502,7 +3905,8 @@ } js_ast.Identifier _emitTypeParameter( - /* TypeParameter | StructuralParameter */ Object t) { + /* TypeParameter | StructuralParameter */ Object t, + ) { assert(t is TypeParameter || t is StructuralParameter); return _emitIdentifier(getTypeParameterName(t)); } @@ -3520,7 +3924,8 @@ void _setIncrementalMode() { if (!_moduleEmitted) { throw StateError( - 'Cannot run in incremental mode before module completion'); + 'Cannot run in incremental mode before module completion', + ); } _incrementalModules.clear(); _privateNames.clear(); @@ -3546,8 +3951,13 @@ /// Triggers incremental mode, which only emits symbols, types, constants, /// libraries, and uris referenced in the expression compilation result. @override - js_ast.Fun emitFunctionIncremental(List<ModuleItem> items, Library library, - Class? cls, FunctionNode functionNode, String name) { + js_ast.Fun emitFunctionIncremental( + List<ModuleItem> items, + Library library, + Class? cls, + FunctionNode functionNode, + String name, + ) { // Setup context. _currentLibrary = library; _staticTypeContext.enterLibrary(_currentLibrary!); @@ -3584,7 +3994,7 @@ ..._symbolContainer.emit(), ..._emitConstTable(), ..._uriContainer.emit(), - ...fun.body.statements + ...fun.body.statements, ]); // Import all necessary libraries, including libraries accessed from the @@ -3601,23 +4011,33 @@ List<js_ast.Statement> _emitConstTable() { var constTable = <js_ast.Statement>[]; if (_constLazyAccessors.isNotEmpty) { - constTable - .add(js.statement('const # = Object.create(null);', [_constTable])); + constTable.add( + js.statement('const # = Object.create(null);', [_constTable]), + ); - constTable.add(_runtimeStatement( - 'defineLazy(#, { # })', [_constTable, _constLazyAccessors])); + constTable.add( + _runtimeStatement('defineLazy(#, { # })', [ + _constTable, + _constLazyAccessors, + ]), + ); constTable.addAll(_constTableCache.emit()); } return constTable; } - js_ast.Fun _emitFunction(FunctionNode f, String? name, - {SourceLocation? functionEnd, SourceLocation? functionBody}) { + js_ast.Fun _emitFunction( + FunctionNode f, + String? name, { + SourceLocation? functionEnd, + SourceLocation? functionBody, + }) { var savedTypeEnvironment = _currentTypeEnvironment; if (f.typeParameters.isNotEmpty) { - _currentTypeEnvironment = - _currentTypeEnvironment.extend(f.typeParameters); + _currentTypeEnvironment = _currentTypeEnvironment.extend( + f.typeParameters, + ); } var formals = _emitParameters(f); var typeFormals = _emitTypeFormals(f.typeParameters); @@ -3631,22 +4051,30 @@ // potentially mutated in Kernel. For now we assume all parameters are. _enterFunction(name, formals, () => true); - var block = js_ast.Block(_withCurrentFunction(f, () { - final bodyPrefix = _emitArgumentInitializers(f, name); + var block = js_ast.Block( + _withCurrentFunction(f, () { + final bodyPrefix = _emitArgumentInitializers(f, name); - // Do the async transformation before adding parameter initialization - // logic. Any parameter initialization should be performed synchronously - // before the async body is evaluated. - final bodyFn = - js_ast.Fun(formals, js_ast.Block([_emitFunctionScopedBody(f)])); - final rewrittenFunction = _rewriteAsyncFunction( - bodyFn, f.asyncMarker, name, f.emittedValueType, + // Do the async transformation before adding parameter initialization + // logic. Any parameter initialization should be performed synchronously + // before the async body is evaluated. + final bodyFn = js_ast.Fun( + formals, + js_ast.Block([_emitFunctionScopedBody(f)]), + ); + final rewrittenFunction = _rewriteAsyncFunction( + bodyFn, + f.asyncMarker, + name, + f.emittedValueType, functionEnd: functionEnd, functionBody: functionBody, - bodyPrefix: bodyPrefix); - formals = rewrittenFunction.params; - return rewrittenFunction.body.statements; - })); + bodyPrefix: bodyPrefix, + ); + formals = rewrittenFunction.params; + return rewrittenFunction.body.statements; + }), + ); block = _exitFunction(formals, block); var fn = js_ast.Fun(formals, block); @@ -3661,11 +4089,15 @@ /// [bodyPrefix] will get prepended to the body of the rewritten function and /// any references to parameters within it will be replaced with the correct /// temporary ID for that parameter. - js_ast.Fun _rewriteAsyncFunction(js_ast.Fun fun, AsyncMarker asyncMarker, - String? name, DartType? asyncType, - {SourceLocation? functionEnd, - SourceLocation? functionBody, - List<js_ast.Statement>? bodyPrefix}) { + js_ast.Fun _rewriteAsyncFunction( + js_ast.Fun fun, + AsyncMarker asyncMarker, + String? name, + DartType? asyncType, { + SourceLocation? functionEnd, + SourceLocation? functionBody, + List<js_ast.Statement>? bodyPrefix, + }) { AsyncRewriterBase? asyncRewriter; final bodyName = _emitScopedId('t\$async${name ?? 'Body'}'); switch (asyncMarker) { @@ -3673,68 +4105,93 @@ break; case AsyncMarker.Async: asyncRewriter = AsyncRewriter( - asyncStart: _emitTopLevelNameNoExternalInterop(_asyncStartMember), - asyncAwait: _emitTopLevelNameNoExternalInterop(_asyncAwaitMember), - asyncReturn: _emitTopLevelNameNoExternalInterop(_asyncReturnMember), - asyncRethrow: - _emitTopLevelNameNoExternalInterop(_asyncRethrowMember), - completerFactory: - _emitTopLevelNameNoExternalInterop(_asyncMakeCompleterMember), - completerFactoryTypeArguments: [ - _emitType(asyncType!), - ], - wrapBody: - _emitTopLevelNameNoExternalInterop(_asyncWrapJsFunctionMember), - bodyName: bodyName); + asyncStart: _emitTopLevelNameNoExternalInterop(_asyncStartMember), + asyncAwait: _emitTopLevelNameNoExternalInterop(_asyncAwaitMember), + asyncReturn: _emitTopLevelNameNoExternalInterop(_asyncReturnMember), + asyncRethrow: _emitTopLevelNameNoExternalInterop(_asyncRethrowMember), + completerFactory: _emitTopLevelNameNoExternalInterop( + _asyncMakeCompleterMember, + ), + completerFactoryTypeArguments: [_emitType(asyncType!)], + wrapBody: _emitTopLevelNameNoExternalInterop( + _asyncWrapJsFunctionMember, + ), + bodyName: bodyName, + ); case AsyncMarker.SyncStar: asyncRewriter = SyncStarRewriter( - makeSyncStarIterable: - _emitTopLevelNameNoExternalInterop(_syncStarMakeIterableMember), - syncStarIterableTypeArgument: _emitType(asyncType!), - iteratorCurrentValueProperty: _emitMemberName('_current', - member: _syncStarIteratorCurrentMember), - iteratorDatumProperty: - _emitMemberName('_datum', member: _syncStarIteratorDatumMember), - yieldStarSelector: _emitMemberName('_yieldStar', - member: _syncStarIteratorYieldStarMember), - bodyName: bodyName); + makeSyncStarIterable: _emitTopLevelNameNoExternalInterop( + _syncStarMakeIterableMember, + ), + syncStarIterableTypeArgument: _emitType(asyncType!), + iteratorCurrentValueProperty: _emitMemberName( + '_current', + member: _syncStarIteratorCurrentMember, + ), + iteratorDatumProperty: _emitMemberName( + '_datum', + member: _syncStarIteratorDatumMember, + ), + yieldStarSelector: _emitMemberName( + '_yieldStar', + member: _syncStarIteratorYieldStarMember, + ), + bodyName: bodyName, + ); case AsyncMarker.AsyncStar: asyncRewriter = AsyncStarRewriter( - asyncStarHelper: - _emitTopLevelNameNoExternalInterop(_asyncStarHelperMember), - streamOfController: _emitTopLevelNameNoExternalInterop( - _asyncStreamOfControllerMember), - newController: _emitTopLevelNameNoExternalInterop( - _asyncMakeAsyncStarStreamControllerMember), - newControllerTypeArguments: [_emitType(asyncType!)], - yieldExpression: - _emitStaticGet(_asyncIterationMarkerYieldSingleMember), - yieldStarExpression: - _emitStaticGet(_asyncIterationMarkerYieldStarMember), - wrapBody: - _emitTopLevelNameNoExternalInterop(_asyncWrapJsFunctionMember), - bodyName: bodyName); + asyncStarHelper: _emitTopLevelNameNoExternalInterop( + _asyncStarHelperMember, + ), + streamOfController: _emitTopLevelNameNoExternalInterop( + _asyncStreamOfControllerMember, + ), + newController: _emitTopLevelNameNoExternalInterop( + _asyncMakeAsyncStarStreamControllerMember, + ), + newControllerTypeArguments: [_emitType(asyncType!)], + yieldExpression: _emitStaticGet( + _asyncIterationMarkerYieldSingleMember, + ), + yieldStarExpression: _emitStaticGet( + _asyncIterationMarkerYieldStarMember, + ), + wrapBody: _emitTopLevelNameNoExternalInterop( + _asyncWrapJsFunctionMember, + ), + bodyName: bodyName, + ); } if (asyncRewriter != null) { - return asyncRewriter.rewrite(fun, functionBody, functionEnd, - bodyPrefix: bodyPrefix); + return asyncRewriter.rewrite( + fun, + functionBody, + functionEnd, + bodyPrefix: bodyPrefix, + ); } else if (bodyPrefix != null) { fun.body.statements.insertAll(0, bodyPrefix); } return fun; } - js_ast.Parameter _emitParameter(VariableDeclaration node, - {bool withoutInitializer = false}) { + js_ast.Parameter _emitParameter( + VariableDeclaration node, { + bool withoutInitializer = false, + }) { var initializer = node.initializer; var id = _emitVariableDef(node); if (initializer == null || withoutInitializer) return id; return js_ast.DestructuredVariable( - name: id, defaultValue: _visitExpression(initializer)); + name: id, + defaultValue: _visitExpression(initializer), + ); } - List<js_ast.Parameter> _emitParameters(FunctionNode f, - {bool isForwarding = false}) { + List<js_ast.Parameter> _emitParameters( + FunctionNode f, { + bool isForwarding = false, + }) { // Destructure optional positional parameters in place. // Given: // - (arg1, arg2, [opt1, opt2 = def2]) @@ -3744,8 +4201,11 @@ // forwarded call not a parameter list. E.g., the second in: // - foo(arg1, opt1 = def1) => super(arg1, opt1). var positional = f.positionalParameters; - var result = List<js_ast.Parameter>.of(positional - .map((p) => _emitParameter(p, withoutInitializer: isForwarding))); + var result = List<js_ast.Parameter>.of( + positional.map( + (p) => _emitParameter(p, withoutInitializer: isForwarding), + ), + ); if (positional.isNotEmpty && f.requiredParameterCount == positional.length && positional.last.annotations.any(isJsRestAnnotation)) { @@ -3756,16 +4216,21 @@ } List<js_ast.Identifier> _emitTypeFormals( - List< /*TypeParameter | StructuralParameter */ Object> typeFormals) { - assert(typeFormals is List<TypeParameter> || - typeFormals is List<StructuralParameter>); + List< /*TypeParameter | StructuralParameter */ Object> typeFormals, + ) { + assert( + typeFormals is List<TypeParameter> || + typeFormals is List<StructuralParameter>, + ); return typeFormals .map((t) => _emitIdentifier(getTypeParameterName(t))) .toList(); } List<js_ast.Statement> _withCurrentFunction( - FunctionNode fn, List<js_ast.Statement> Function() action) { + FunctionNode fn, + List<js_ast.Statement> Function() action, + ) { var savedFunction = _currentFunction; _currentFunction = fn; _nullableInference.enterFunction(fn); @@ -3806,13 +4271,18 @@ /// Emits argument initializers, which handles optional/named args, as well /// as generic type checks needed due to our covariance. List<js_ast.Statement> _emitArgumentInitializers( - FunctionNode f, String? name) { + FunctionNode f, + String? name, + ) { var body = <js_ast.Statement>[]; _emitCovarianceBoundsCheck(f.typeParameters, body); void initParameter( - VariableDeclaration p, js_ast.Identifier jsParam, bool isOptional) { + VariableDeclaration p, + js_ast.Identifier jsParam, + bool isOptional, + ) { // When the parameter is covariant, insert the null check before the // covariant cast to avoid a TypeError when testing equality with null. if (name == '==') { @@ -3863,14 +4333,16 @@ var jsParam = _emitVariableDef(p); var paramName = _propertyName(p.name!); var defaultValue = _defaultParamValue(p); - body.add(js.statement('let # = # && # ? #.# : #;', [ - jsParam, - _namedArgumentTemp, - _namedArgumentProbe(paramName), - _namedArgumentTemp, - paramName, - defaultValue, - ])); + body.add( + js.statement('let # = # && # ? #.# : #;', [ + jsParam, + _namedArgumentTemp, + _namedArgumentProbe(paramName), + _namedArgumentTemp, + paramName, + defaultValue, + ]), + ); if (_checkParameters) { initParameter(p, jsParam, !p.isRequired); @@ -3895,8 +4367,9 @@ // JS interop members should not pass type arguments. !isJsMember(m) && !(m.enclosingLibrary.importUri.isScheme('dart') && - m.annotations.any((a) => - isBuiltinAnnotation(a, '_js_helper', 'NoReifyGeneric'))); + m.annotations.any( + (a) => isBuiltinAnnotation(a, '_js_helper', 'NoReifyGeneric'), + )); js_ast.Statement _nullParameterCheck(js_ast.Expression param) { var call = _runtimeCall('argumentError((#))', [param]); @@ -3922,10 +4395,13 @@ : js.call('# in #', [propertyName, _namedArgumentTemp]); void _emitCovarianceBoundsCheck( - List< /* TypeParameter | StructuralParameter */ Object> typeFormals, - List<js_ast.Statement> body) { - assert(typeFormals is List<TypeParameter> || - typeFormals is List<StructuralParameter>); + List< /* TypeParameter | StructuralParameter */ Object> typeFormals, + List<js_ast.Statement> body, + ) { + assert( + typeFormals is List<TypeParameter> || + typeFormals is List<StructuralParameter>, + ); for (var t in typeFormals) { bool? isCovariantByClass; DartType bound; @@ -3940,18 +4416,22 @@ t as StructuralParameter; bound = t.bound.extensionTypeErasure; name = t.name!; - typeParameterType = - StructuralParameterType(t, Nullability.undetermined); + typeParameterType = StructuralParameterType( + t, + Nullability.undetermined, + ); } if (isCovariantByClass != null && isCovariantByClass && !_types.isTop(bound)) { - body.add(_runtimeStatement('checkTypeBound(#, #, #)', [ - _emitType(typeParameterType), - _emitType(bound), - _propertyName(name) - ])); + body.add( + _runtimeStatement('checkTypeBound(#, #, #)', [ + _emitType(typeParameterType), + _emitType(bound), + _propertyName(name), + ]), + ); } } } @@ -4038,8 +4518,10 @@ } if (node is AsExpression && node.isTypeError) { - assert(node.getStaticType(_staticTypeContext) == - _types.coreTypes.boolNonNullableRawType); + assert( + node.getStaticType(_staticTypeContext) == + _types.coreTypes.boolNonNullableRawType, + ); return _runtimeCall('dtest(#)', [_visitExpression(node.operand)]); } @@ -4098,8 +4580,12 @@ try { var loc = _component.getLocation(fileUri, offset); if (loc == null || loc.line < 0) return null; - return SourceLocation(offset, - sourceUrl: fileUri, line: loc.line - 1, column: loc.column - 1); + return SourceLocation( + offset, + sourceUrl: fileUri, + line: loc.line - 1, + column: loc.column - 1, + ); } on StateError catch (_) { // TODO(jmesserly): figure out why this is throwing. Perhaps the file URI // and offset are mismatched and don't correspond to the same source? @@ -4116,7 +4602,10 @@ /// on the library/class, so their access expressions do not appear in the /// source code. HoverComment? _hoverComment( - js_ast.Expression expr, int offset, int nameLength) { + js_ast.Expression expr, + int offset, + int nameLength, + ) { var start = _toSourceLocation(offset); var end = _toSourceLocation(offset + nameLength); return start != null && end != null ? HoverComment(expr, start, end) : null; @@ -4146,8 +4635,10 @@ // slightly different (in Dart, there is a nested scope), but that's handled // by _emitSyncFunctionBody. var isScope = !identical(node.parent, _currentFunction); - return js_ast.Block(node.statements.map(_visitStatement).toList(), - isScope: isScope); + return js_ast.Block( + node.statements.map(_visitStatement).toList(), + isScope: isScope, + ); } @override @@ -4193,8 +4684,10 @@ if (assertLocation != null) { var fileUri = assertLocation.file; var source = node.enclosingComponent!.uriToSource[fileUri]!.text; - conditionSource = - source.substring(node.conditionStartOffset, node.conditionEndOffset); + conditionSource = source.substring( + node.conditionStartOffset, + node.conditionEndOffset, + ); // Assertions that appear in debugger expressions have a synthetic Uri // that is different than the current library where the expression will // be evaluated. @@ -4222,7 +4715,7 @@ js.number(location == null ? -1 : location.line + 1), js.number(location == null ? -1 : location.column + 1), js.escapedString(conditionSource), - ]) + ]), ]); } @@ -4329,7 +4822,9 @@ } T _translateLoop<T extends js_ast.Statement>( - Statement node, T Function() action) { + Statement node, + T Function() action, + ) { List<LabeledStatement>? savedBreakTargets; if (_currentBreakTargets.isNotEmpty && _effectiveTargets[_currentBreakTargets.first] != node) { @@ -4370,8 +4865,10 @@ js_ast.Statement visitForStatement(ForStatement node) { return _translateLoop(node, () { js_ast.VariableInitialization emitForInitializer(VariableDeclaration v) => - js_ast.VariableInitialization(_emitVariableDef(v), - _visitInitializer(v.initializer, v.annotations)); + js_ast.VariableInitialization( + _emitVariableDef(v), + _visitInitializer(v.initializer, v.annotations), + ); if (node.variables.any(containsFunctionExpression)) { return _rewriteAsWhile(node); @@ -4383,8 +4880,9 @@ js_ast.Expression? update; if (updates.isNotEmpty) { update = js_ast.Expression.binary( - updates.map(_visitExpression).toList(), ',') - .toVoidExpression(); + updates.map(_visitExpression).toList(), + ',', + ).toVoidExpression(); } var condition = node.condition != null ? _visitTest(node.condition!) : null; @@ -4395,13 +4893,13 @@ } /// Rewrites a `for(;;)` style loop as a while loop to produce the correct - /// semantics when loop variable initialziers contain function expressions + /// semantics when loop variable initializers contain function expressions /// that close over other loop variables. /// /// The Dart semantics expect that every loop iteration gets fresh loop /// variables that can be closed over. The initialization is only executed /// for the first iteration. In later iterations, the fresh loop variables are - /// initalized to the values from the end of the previous iteration. + /// initialized to the values from the end of the previous iteration. /// /// These semantics differ from JavaScript when there are closures capturing /// loop variables so the simple lowering doesn't work as expected. @@ -4451,55 +4949,65 @@ for (var variable in node.variables) js.statement('# = #;', [ loopVariableIds[variable]!, - _visitInitializer(variable.initializer, variable.annotations) + _visitInitializer(variable.initializer, variable.annotations), ]), ]); var prevInits = js_ast.Block([ - // Intialize fresh loop variables with the value from the previous + // Initialize fresh loop variables with the value from the previous // iteration. for (var variable in node.variables) - js.statement('# = #;', - [loopVariableIds[variable], prevVariableTempIds[variable]]), + js.statement('# = #;', [ + loopVariableIds[variable], + prevVariableTempIds[variable], + ]), // Original update expressions. for (var update in node.updates) _visitExpression(update).toStatement(), ]); return js_ast.Block([ - // Create temporary variables for the intialization flag and previous + // Create temporary variables for the initialization flag and previous // loop variables. js_ast.VariableDeclarationList('let', [ - js_ast.VariableInitialization(initFlagTempId, js_ast.LiteralBool(true)), + js_ast.VariableInitialization( + initFlagTempId, + js_ast.LiteralBool(true), + ), for (var variable in node.variables) js_ast.VariableInitialization(prevVariableTempIds[variable]!, null), ]).toStatement(), // The for loop transformed into a while loop. js_ast.While( - js_ast.LiteralBool(true), - js_ast.Block([ - // Create fresh loop variables every iteration. - if (node.variables.isNotEmpty) - js_ast.VariableDeclarationList('let', [ - for (var variable in node.variables) - js_ast.VariableInitialization( - loopVariableIds[variable]!, null) - ]).toStatement(), - // Initialize loop variables. - js_ast.If(initFlagTempId, inits, prevInits), - // Loop condition guard. - if (node.condition != null) - js.statement('if (!#) break;', [_visitTest(node.condition!)]) - ..sourceInformation = _nodeStart(node.condition!), - // Original loop body. - _visitScope(_effectiveBodyOf(node, node.body)), - // Save previous loop variables - for (var variable in node.variables) - js.statement('# = #;', - [prevVariableTempIds[variable]!, _emitVariableRef(variable)]) - // Map these locations to the variable declaration so stepping - // in the Dart debugger doesn't jump to the previous line when - // stepping. - ..sourceInformation = _nodeStart(variable), - ])) - // The while loop gets mapped to the orginal for loop location. + js_ast.LiteralBool(true), + js_ast.Block([ + // Create fresh loop variables every iteration. + if (node.variables.isNotEmpty) + js_ast.VariableDeclarationList('let', [ + for (var variable in node.variables) + js_ast.VariableInitialization( + loopVariableIds[variable]!, + null, + ), + ]).toStatement(), + // Initialize loop variables. + js_ast.If(initFlagTempId, inits, prevInits), + // Loop condition guard. + if (node.condition != null) + js.statement('if (!#) break;', [_visitTest(node.condition!)]) + ..sourceInformation = _nodeStart(node.condition!), + // Original loop body. + _visitScope(_effectiveBodyOf(node, node.body)), + // Save previous loop variables + for (var variable in node.variables) + js.statement('# = #;', [ + prevVariableTempIds[variable]!, + _emitVariableRef(variable), + ]) + // Map these locations to the variable declaration so stepping + // in the Dart debugger doesn't jump to the previous line when + // stepping. + ..sourceInformation = _nodeStart(variable), + ]), + ) + // The while loop gets mapped to the original for loop location. ..sourceInformation = _nodeStart(node), ]) // Clear the source mapping on the outer block so it doesn't automatically @@ -4518,8 +5026,10 @@ var init = js.call('let #', _emitVariableDef(node.variable)); if (_annotatedNullCheck(node.variable.annotations)) { - body = js_ast.Block( - [_nullParameterCheck(_emitVariableRef(node.variable)), body]); + body = js_ast.Block([ + _nullParameterCheck(_emitVariableRef(node.variable)), + body, + ]); } if (node.variable.name != null && @@ -4527,7 +5037,7 @@ var temp = _emitScopedId('iter'); return js_ast.Block([ iterable.toVariableDeclaration(temp), - js_ast.ForOf(init, temp, body) + js_ast.ForOf(init, temp, body), ]); } return js_ast.ForOf(init, iterable, body); @@ -4552,15 +5062,19 @@ // // TODO(jmesserly): we may want a helper if these become common. For now the // full desugaring seems okay. - var streamIterator = - _coreTypes.nonNullableRawType(_asyncStreamIteratorClass); + var streamIterator = _coreTypes.nonNullableRawType( + _asyncStreamIteratorClass, + ); var streamIteratorRti = _emitType(streamIterator); var createStreamIter = js_ast.Call( - _emitConstructorName( - streamIterator, - _asyncStreamIteratorClass.procedures - .firstWhere((p) => p.isFactory && p.name.text == '')), - [streamIteratorRti, _visitExpression(node.iterable)]); + _emitConstructorName( + streamIterator, + _asyncStreamIteratorClass.procedures.firstWhere( + (p) => p.isFactory && p.name.text == '', + ), + ), + [streamIteratorRti, _visitExpression(node.iterable)], + ); var iter = _emitScopedId('iter'); @@ -4573,7 +5087,7 @@ ..sourceInformation = _nodeStart(node.variable), _emitVariableDef(node.variable), iter, - _visitStatement(node.body) + _visitStatement(node.body), ]); // Any label on the Dart loop statement should target the inner loop rather @@ -4584,14 +5098,17 @@ } var awaitForStmt = js_ast.Block([ - js_ast.ExpressionStatement(js_ast.VariableDeclarationList( - 'let', [js_ast.VariableInitialization(iter, createStreamIter)]) - ..sourceInformation = _nodeStart(node.iterable)), + js_ast.ExpressionStatement( + js_ast.VariableDeclarationList('let', [ + js_ast.VariableInitialization(iter, createStreamIter), + ]) + ..sourceInformation = _nodeStart(node.iterable), + ), js.statement('try { # } finally { #; }', [ loopStmt, js_ast.Await(js.call('#.cancel()', iter)) - ..sourceInformation = _nodeStart(node.variable) - ]) + ..sourceInformation = _nodeStart(node.variable), + ]), ], isScope: true); _currentContinueTargets = savedContinueTargets; @@ -4623,8 +5140,10 @@ _currentContinueTargets = []; for (var c in node.cases) { - var subcases = - _visitSwitchCase(c, lastSwitchCase: c == node.cases.last); + var subcases = _visitSwitchCase( + c, + lastSwitchCase: c == node.cases.last, + ); if (subcases.isNotEmpty) cases.addAll(subcases); } _currentContinueTargets = savedCurrentContinueTargets; @@ -4638,7 +5157,7 @@ var labeledStmt = js_ast.LabeledStatement(labelName, loopStmt); var block = js_ast.Block([ js.statement('let # = #', [labelState, switchExpr]), - labeledStmt + labeledStmt, ]); _inLabeledContinueSwitch = previous; return block; @@ -4660,8 +5179,10 @@ /// labeled continues. Dart permits the final case to implicitly break, but /// switch statements with labeled continues must explicitly break/continue /// to escape the surrounding infinite loop. - List<js_ast.SwitchClause> _visitSwitchCase(SwitchCase node, - {bool lastSwitchCase = false}) { + List<js_ast.SwitchClause> _visitSwitchCase( + SwitchCase node, { + bool lastSwitchCase = false, + }) { var cases = <js_ast.SwitchClause>[]; var emptyBlock = js_ast.Block.empty(); // TODO(jmesserly): make sure we are statically checking fall through @@ -4714,8 +5235,9 @@ return js_ast.Block([setStateStmt, continueStmt]); } return _emitInvalidNode( - node, 'see https://github.com/dart-lang/sdk/issues/29352') - .toStatement(); + node, + 'see https://github.com/dart-lang/sdk/issues/29352', + ).toStatement(); } @override @@ -4763,7 +5285,10 @@ @override js_ast.Statement visitTryCatch(TryCatch node) { return js_ast.Try( - _visitStatement(node.body).toBlock(), _visitCatch(node.catches), null); + _visitStatement(node.body).toBlock(), + _visitCatch(node.catches), + null, + ); } js_ast.Catch? _visitCatch(List<Catch> clauses) { @@ -4788,40 +5313,53 @@ js_ast.Statement catchBody = js_ast.Throw(_emitVariableRef(caughtError)); for (var clause in clauses.reversed) { catchBody = _catchClauseGuard( - clause, catchBody, exceptionParameter, stackTraceParameter); + clause, + catchBody, + exceptionParameter, + stackTraceParameter, + ); } var catchStatements = [ js.statement('let # = #', [ _emitVariableDef(exceptionParameter), - _runtimeCall('getThrown(#)', [_emitVariableRef(caughtError)]) + _runtimeCall('getThrown(#)', [_emitVariableRef(caughtError)]), ]), if (stackTraceParameter != null) js.statement('let # = #', [ _emitVariableDef(stackTraceParameter), - _runtimeCall('stackTrace(#)', [_emitVariableRef(caughtError)]) + _runtimeCall('stackTrace(#)', [_emitVariableRef(caughtError)]), ]), catchBody, ]; _rethrowParameter = savedRethrow; - return js_ast.Catch(_emitVariableDef(caughtError), - js_ast.Block(catchStatements, isScope: true)); + return js_ast.Catch( + _emitVariableDef(caughtError), + js_ast.Block(catchStatements, isScope: true), + ); } js_ast.Statement _catchClauseGuard( - Catch node, - js_ast.Statement otherwise, - VariableDeclaration exceptionParameter, - VariableDeclaration? stackTraceParameter) { + Catch node, + js_ast.Statement otherwise, + VariableDeclaration exceptionParameter, + VariableDeclaration? stackTraceParameter, + ) { var body = <js_ast.Statement>[]; var vars = HashSet<String>(); void declareVariable( - VariableDeclaration? variable, VariableDeclaration? value) { + VariableDeclaration? variable, + VariableDeclaration? value, + ) { if (variable == null || value == null) return; vars.add(variable.name!); if (variable.name != value.name) { - body.add(js.statement('let # = #', - [_emitVariableDef(variable), _emitVariableRef(value)])); + body.add( + js.statement('let # = #', [ + _emitVariableDef(variable), + _emitVariableRef(value), + ]), + ); } } @@ -4835,8 +5373,10 @@ // Discard following clauses, if any, as they are unreachable. if (_types.isTop(guardType)) return then; - var condition = - _emitIsExpression(VariableGet(exceptionParameter), guardType); + var condition = _emitIsExpression( + VariableGet(exceptionParameter), + guardType, + ); return js_ast.If(condition, then, otherwise) ..sourceInformation = _nodeStart(node); } @@ -4844,8 +5384,9 @@ @override js_ast.Statement visitTryFinally(TryFinally node) { var body = _visitStatement(node.body); - var finallyBlock = - _superDisallowed(() => _visitStatement(node.finalizer).toBlock()); + var finallyBlock = _superDisallowed( + () => _visitStatement(node.finalizer).toBlock(), + ); if (body is js_ast.Try && body.finallyPart == null) { // Kernel represents Dart try/catch/finally as try/catch nested inside of @@ -4859,7 +5400,9 @@ @override js_ast.Statement visitYieldStatement(YieldStatement node) { return js_ast.DartYield( - _visitExpression(node.expression), node.isYieldStar); + _visitExpression(node.expression), + node.isYieldStar, + ); } @override @@ -4867,8 +5410,10 @@ // TODO(jmesserly): casts are sometimes required here. // Kernel does not represent these explicitly. var v = _emitVariableDef(node); - return js.statement('let # = #;', - [v, _visitInitializer(node.initializer, node.annotations)]); + return js.statement('let # = #;', [ + v, + _visitInitializer(node.initializer, node.annotations), + ]); } @override @@ -4882,9 +5427,10 @@ if (_reifyFunctionType(func)) { declareFn = js_ast.Block([ declareFn, - _emitFunctionTagged(_emitVariableRef(node.variable), - func.computeThisFunctionType(Nullability.nonNullable)) - .toStatement() + _emitFunctionTagged( + _emitVariableRef(node.variable), + func.computeThisFunctionType(Nullability.nonNullable), + ).toStatement(), ]); } return declareFn; @@ -4904,7 +5450,8 @@ var id = _emitVariableRef(v); if (id.name == v.name) { id = id.withSourceInformation( - _variableSpan(node.fileOffset, v.name!.length)); + _variableSpan(node.fileOffset, v.name!.length), + ); } return id; } @@ -4943,7 +5490,9 @@ var name = _debuggerFriendlyTemporaryVariableName(v); name ??= 't\$${_tempVariables.length}'; return _tempVariables.putIfAbsent( - v, () => _emitScopedId(name!, needsCapture: true)); + v, + () => _emitScopedId(name!, needsCapture: true), + ); } var name = v.name!; if (isLateLoweredLocal(v)) { @@ -4954,7 +5503,8 @@ name = extractLocalNameFromLateLoweredLocal(name); } return js_ast.ScopedId.from( - _variableTempIds[v] ??= _emitScopedId(name, needsCapture: true)); + _variableTempIds[v] ??= _emitScopedId(name, needsCapture: true), + ); } /// Emits the declaration of a variable. @@ -4970,9 +5520,10 @@ js_ast.Statement? _initLetVariables() { var letVars = _letVariables!; if (letVars.isEmpty) return null; - var result = js_ast.VariableDeclarationList('let', - letVars.map((v) => js_ast.VariableInitialization(v, null)).toList()) - .toStatement(); + var result = js_ast.VariableDeclarationList( + 'let', + letVars.map((v) => js_ast.VariableInitialization(v, null)).toList(), + ).toStatement(); letVars.clear(); return result; } @@ -4984,9 +5535,9 @@ // hand side, to help normalize the inconsistent locations of the CFE // lowerings for ++x, x++, x+=, etc. // See https://github.com/dart-lang/sdk/issues/55691. - return _visitExpression(node.value) - .toAssignExpression(_emitVariableRef(node.variable)) - ..sourceInformation = _nodeStart(node.value); + return _visitExpression(node.value).toAssignExpression( + _emitVariableRef(node.variable), + )..sourceInformation = _nodeStart(node.value); } @override @@ -5021,8 +5572,10 @@ return _runtimeCall('#(#)', [memberName, jsReceiver]); } // Otherwise generate this as a normal typed property get. - var jsMemberName = - _emitMemberName(memberName, member: node.interfaceTarget); + var jsMemberName = _emitMemberName( + memberName, + member: node.interfaceTarget, + ); var instanceGet = js_ast.PropertyAccess(jsReceiver, jsMemberName); return _isNullCheckableJsInterop(node.interfaceTarget) ? _wrapWithJsInteropNullCheck(instanceGet) @@ -5038,9 +5591,13 @@ _emitRecordElementGet(node.receiver, node.name); js_ast.Expression _emitRecordElementGet( - Expression receiver, String elementName) => + Expression receiver, + String elementName, + ) => js_ast.PropertyAccess( - _visitExpression(receiver), _emitMemberName(elementName)); + _visitExpression(receiver), + _emitMemberName(elementName), + ); @override js_ast.Expression visitInstanceTearOff(InstanceTearOff node) { @@ -5070,8 +5627,10 @@ } var jsPropertyAccess = js_ast.PropertyAccess(jsReceiver, jsMemberName); return isJsMember(member) - ? _runtimeCall('tearoffInterop(#, #)', - [jsPropertyAccess, js.boolean(_isNullCheckableJsInterop(member))]) + ? _runtimeCall('tearoffInterop(#, #)', [ + jsPropertyAccess, + js.boolean(_isNullCheckableJsInterop(member)), + ]) : jsPropertyAccess; } @@ -5085,7 +5644,7 @@ return _runtimeCall('dput$_replSuffix(#, #, #)', [ _visitExpression(node.receiver), _emitMemberName(node.name.text), - _visitExpression(node.value) + _visitExpression(node.value), ]); } @@ -5096,7 +5655,7 @@ return js.call('#.# = #', [ _visitExpression(node.receiver), _emitMemberName(node.name.text, member: target), - _visitExpression(value) + _visitExpression(value), ]); } @@ -5189,7 +5748,8 @@ @override js_ast.Expression visitAbstractSuperPropertyGet( - AbstractSuperPropertyGet node) { + AbstractSuperPropertyGet node, + ) { return _emitSuperPropertyGet(node.interfaceTarget); } @@ -5208,8 +5768,10 @@ if (!mixedInClass.isAnonymousMixin) { mixinName += '#${baseClass.name}'; } - return _mixinCache - .putIfAbsent((mixedInClass, baseClass), () => _emitScopedId(mixinName)); + return _mixinCache.putIfAbsent(( + mixedInClass, + baseClass, + ), () => _emitScopedId(mixinName)); } js_ast.Expression _emitSuperPropertyGet(Member target) { @@ -5224,14 +5786,19 @@ var mixinId = _emitMixinId(enclosingClass, enclosingClass); var enclosingLibrary = _emitLibraryName(getLibrary(enclosingClass)); supertypeReference = js_ast.PropertyAccess( - enclosingLibrary, js.string(mixinId.name)); + enclosingLibrary, + js.string(mixinId.name), + ); } else { - supertypeReference = - _emitTopLevelNameNoExternalInterop(enclosingClass); + supertypeReference = _emitTopLevelNameNoExternalInterop( + enclosingClass, + ); } } - return _runtimeCall( - 'superTearoff(this, #, #)', [supertypeReference, jsName]); + return _runtimeCall('superTearoff(this, #, #)', [ + supertypeReference, + jsName, + ]); } else { return _emitSuperTearoffFromDisallowedContext(target); } @@ -5241,7 +5808,8 @@ @override js_ast.Expression visitAbstractSuperPropertySet( - AbstractSuperPropertySet node) { + AbstractSuperPropertySet node, + ) { return _emitSuperPropertySet(node.interfaceTarget, node.value); } @@ -5280,10 +5848,14 @@ var property = propertyAccessor.selector; var result = js.call('#.#', [context, property]); if (_reifyTearoff(target)) { - var enclosingMemberTargetName = - js.string(fullyResolvedTargetLabel(target)); - return _runtimeCall('staticTearoff(#, #, #)', - [context, enclosingMemberTargetName, property]); + var enclosingMemberTargetName = js.string( + fullyResolvedTargetLabel(target), + ); + return _runtimeCall('staticTearoff(#, #, #)', [ + context, + enclosingMemberTargetName, + property, + ]); } return result; } @@ -5299,7 +5871,10 @@ @override js_ast.Expression visitDynamicInvocation(DynamicInvocation node) { return _emitDynamicInvocation( - node.receiver, node.name.text, node.arguments); + node.receiver, + node.name.text, + node.arguments, + ); } @override @@ -5314,7 +5889,9 @@ return _emitDynamicInvocation(node.receiver, name, node.arguments); } return js_ast.Call( - _visitExpression(node.receiver), _emitArgumentList(node.arguments)); + _visitExpression(node.receiver), + _emitArgumentList(node.arguments), + ); } @override @@ -5327,14 +5904,18 @@ @override js_ast.Expression visitInstanceGetterInvocation( - InstanceGetterInvocation node) { + InstanceGetterInvocation node, + ) { if (node.functionType == null) { // A `null` here implies the receiver must be typed as `dynamic` or // `Function`. There isn't any more type information available at compile // time to know this invocation is sound so a dynamic call will handle the // checks at runtime. return _emitDynamicInvocation( - node.receiver, node.name.text, node.arguments); + node.receiver, + node.name.text, + node.arguments, + ); } var getterInvocation = _emitInstanceGetterInvocation(node); return _isNullCheckableJsInterop(node.interfaceTarget) @@ -5343,10 +5924,13 @@ } js_ast.Expression _emitInstanceGetterInvocation( - InstanceGetterInvocation node) { + InstanceGetterInvocation node, + ) { var receiver = _visitExpression(node.receiver); - var arguments = - _emitArgumentList(node.arguments, target: node.interfaceTarget); + var arguments = _emitArgumentList( + node.arguments, + target: node.interfaceTarget, + ); if (node.name.text == 'call') { // Erasing the extension types here to support existing callable behavior // on the old style JS interop types that are callable. This should be @@ -5359,8 +5943,10 @@ return js_ast.Call(receiver, arguments); } } - var memberName = - _emitMemberName(node.name.text, member: node.interfaceTarget); + var memberName = _emitMemberName( + node.name.text, + member: node.interfaceTarget, + ); // We must erase the extension type to potentially find the `call` method. // If the extension type has a runtime representation with a `call`: // @@ -5391,19 +5977,27 @@ assert(node.name.text == 'call'); final localName = VariableGet(node.variable)..fileOffset = node.fileOffset; return js_ast.Call( - _visitExpression(localName), _emitArgumentList(node.arguments)); + _visitExpression(localName), + _emitArgumentList(node.arguments), + ); } @override js_ast.Expression visitEqualsCall(EqualsCall node) { - return _emitEqualityOperator(node.left, node.interfaceTarget, node.right, - negated: false); + return _emitEqualityOperator( + node.left, + node.interfaceTarget, + node.right, + negated: false, + ); } @override js_ast.Expression visitEqualsNull(EqualsNull node) { - return _emitCoreIdenticalCall([node.expression, NullLiteral()], - negated: false); + return _emitCoreIdenticalCall([ + node.expression, + NullLiteral(), + ], negated: false); } js_ast.Expression _emitInstanceInvocation(InstanceInvocation node) { @@ -5454,7 +6048,11 @@ return _emitUnaryOperator(receiver, target, node); } else if (argLength == 1) { return _emitBinaryOperator( - receiver, target, arguments.positional[0], node); + receiver, + target, + arguments.positional[0], + node, + ); } } var jsReceiver = _visitExpression(receiver); @@ -5491,7 +6089,10 @@ /// or `dgsend` to perform dynamic checks before invoking [memberName] on /// [receiver] and passing [arguments]. js_ast.Expression _emitDynamicInvocation( - Expression receiver, String memberName, Arguments arguments) { + Expression receiver, + String memberName, + Arguments arguments, + ) { var jsArgs = [_visitExpression(receiver)]; String jsCode; var (:typeArguments, :positionalArguments, :namedArguments) = @@ -5539,7 +6140,10 @@ } js_ast.Expression _emitUnaryOperator( - Expression expr, Member? target, InvocationExpression node) { + Expression expr, + Member? target, + InvocationExpression node, + ) { var op = node.name.text; if (target != null) { var dispatchType = _coreTypes.nonNullableRawType(target.enclosingClass!); @@ -5547,7 +6151,9 @@ if (op == '~') { if (_typeRep.isNumber(dispatchType)) { return _coerceBitOperationResultToUnsigned( - node, js.call('~#', _notNull(expr))); + node, + js.call('~#', _notNull(expr)), + ); } return _emitOperatorCall(expr, target, op, []); } @@ -5563,7 +6169,9 @@ /// JavaScript operations interpret their operands as signed and generate /// signed results. js_ast.Expression _coerceBitOperationResultToUnsigned( - Expression node, js_ast.Expression uncoerced) { + Expression node, + js_ast.Expression uncoerced, + ) { // Don't coerce if the parent will coerce. var parent = node.parent; if (parent is InvocationExpression && _nodeIsBitwiseOperation(parent)) { @@ -5716,8 +6324,12 @@ return bitWidth(expr, 0) < 32; } - js_ast.Expression _emitBinaryOperator(Expression left, Member? target, - Expression right, InvocationExpression node) { + js_ast.Expression _emitBinaryOperator( + Expression left, + Member? target, + Expression right, + InvocationExpression node, + ) { var op = node.name.text; if (op == '==') return _emitEqualityOperator(left, target, right); @@ -5760,7 +6372,7 @@ return js.call('(# / #).#()', [ _notNull(left), _notNull(right), - _emitMemberName('truncate', memberClass: targetClass) + _emitMemberName('truncate', memberClass: targetClass), ]); case '%': @@ -5791,8 +6403,9 @@ if (_isDefinitelyNonNegative(left) && shiftCount != null) { return binary('# >>> #'); } - // If the context selects out only bits that can't be affected by the - // sign position we can use any JavaScript shift, `(x >> 6) & 3`. + // If the context selects out only bits that can't be affected by + // the sign position we can use any JavaScript shift, + // `(x >> 6) & 3`. if (shiftCount != null && _parentMasksToWidth(node, 31 - shiftCount)) { return binary('# >> #'); @@ -5801,13 +6414,15 @@ case '<<': if (_is31BitUnsigned(node)) { - // Result is 31 bit unsigned which implies the shift count was small - // enough not to pollute the sign bit. + // Result is 31 bit unsigned which implies the shift count was + // small enough not to pollute the sign bit. return binary('# << #'); } if (_asIntInRange(right, 0, 31) != null) { return _coerceBitOperationResultToUnsigned( - node, binary('# << #')); + node, + binary('# << #'), + ); } return _emitOperatorCall(left, target, op, [right]); @@ -5828,8 +6443,11 @@ } js_ast.Expression _emitEqualityOperator( - Expression left, Member? target, Expression right, - {bool negated = false}) { + Expression left, + Member? target, + Expression right, { + bool negated = false, + }) { var targetClass = target?.enclosingClass; var leftType = left.getStaticType(_staticTypeContext).extensionTypeErasure; @@ -5867,15 +6485,17 @@ // The LHS isn't guaranteed to have an equals method we need to use a // runtime helper. return js.call(negated ? '!#' : '#', [ - _runtimeCall( - 'equals(#, #)', [_visitExpression(left), _visitExpression(right)]) + _runtimeCall('equals(#, #)', [ + _visitExpression(left), + _visitExpression(right), + ]), ]); } // Otherwise it is safe to call the equals method on the LHS directly. return js.call(negated ? '!#[#](#)' : '#[#](#)', [ _visitExpression(left), _emitMemberName('==', memberClass: targetClass), - _visitExpression(right) + _visitExpression(right), ]); } @@ -5885,7 +6505,11 @@ /// `obj.name(args)` because that could be a getter followed by a call. /// See [visitMethodInvocation]. js_ast.Expression _emitOperatorCall( - Expression receiver, Member? target, String name, List<Expression> args) { + Expression receiver, + Member? target, + String name, + List<Expression> args, + ) { // TODO(jmesserly): calls that don't pass `element` are probably broken for // `super` calls from disallowed super locations. var memberName = _emitMemberName(name, member: target); @@ -5893,26 +6517,32 @@ // dynamic dispatch var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name]; if (dynamicHelper != null) { - return _runtimeCall('$dynamicHelper(#, #)', - [_visitExpression(receiver), _visitExpressionList(args)]); + return _runtimeCall('$dynamicHelper(#, #)', [ + _visitExpression(receiver), + _visitExpressionList(args), + ]); } else { return _runtimeCall('dsend(#, #, [#])', [ _visitExpression(receiver), memberName, - _visitExpressionList(args) + _visitExpressionList(args), ]); } } // Generic dispatch to a statically known method. - return js.call('#.#(#)', - [_visitExpression(receiver), memberName, _visitExpressionList(args)]); + return js.call('#.#(#)', [ + _visitExpression(receiver), + memberName, + _visitExpressionList(args), + ]); } // TODO(jmesserly): optimize super operators for kernel @override js_ast.Expression visitAbstractSuperMethodInvocation( - AbstractSuperMethodInvocation node) { + AbstractSuperMethodInvocation node, + ) { return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments); } @@ -5922,9 +6552,13 @@ } js_ast.Expression _emitSuperMethodInvocation( - Member target, Arguments arguments) { + Member target, + Arguments arguments, + ) { return js_ast.Call( - _emitSuperTarget(target), _emitArgumentList(arguments, target: target)); + _emitSuperTarget(target), + _emitArgumentList(arguments, target: target), + ); } /// Emits the [js_ast.PropertyAccess] for accessors or method calls to @@ -5958,17 +6592,24 @@ var jsMethod = _superHelpers.putIfAbsent('$lookupPrefix$name', () { var isAccessor = member is Procedure ? member.isAccessor : true; if (isAccessor) { - assert(member is Procedure - ? member.isSetter == setter - : !setter || !(member as Field).isFinal); + assert( + member is Procedure + ? member.isSetter == setter + : !setter || !(member as Field).isFinal, + ); var fn = js.fun( - setter - ? 'function(x) { super[#] = x; }' - : 'function() { return super[#]; }', - [jsName]); + setter + ? 'function(x) { super[#] = x; }' + : 'function() { return super[#]; }', + [jsName], + ); - return js_ast.Method(_emitScopedId(name), fn, - isGetter: !setter, isSetter: setter); + return js_ast.Method( + _emitScopedId(name), + fn, + isGetter: !setter, + isSetter: setter, + ); } else { var function = member.function; var params = [ @@ -5978,8 +6619,11 @@ if (function.namedParameters.isNotEmpty) _namedArgumentTemp, ]; - var fn = js.fun( - 'function(#) { return super[#](#); }', [params, jsName, params]); + var fn = js.fun('function(#) { return super[#](#); }', [ + params, + jsName, + params, + ]); name = js_ast.friendlyNameForDartOperator[name] ?? name; return js_ast.Method(_emitScopedId(name), fn); } @@ -6019,8 +6663,10 @@ var superclass = member.enclosingClass!; var supertypeReference = _mixinSuperclassCache[superclass] ?? _emitTopLevelNameNoExternalInterop(superclass); - var jsReturnValue = _runtimeCall( - 'superTearoff(this, #, #)', [supertypeReference, jsName]); + var jsReturnValue = _runtimeCall('superTearoff(this, #, #)', [ + supertypeReference, + jsName, + ]); var fn = js.fun('function() { return #; }', [jsReturnValue]); name = js_ast.friendlyNameForDartOperator[name] ?? name; return js_ast.Method(_emitScopedId(name), fn); @@ -6120,19 +6766,22 @@ var extractionType = node.arguments.types.single; if (extractionType is! InterfaceType) { throw UnsupportedError( - 'Type arguments can only be extracted from interface types: ' - 'found $extractionType (${extractionType.runtimeType}) at ' - '${node.location}'); + 'Type arguments can only be extracted from interface types: ' + 'found $extractionType (${extractionType.runtimeType}) at ' + '${node.location}', + ); } var extractionTypeParameters = extractionType.classNode.typeParameters; if (extractionTypeParameters.isEmpty) { throw UnsupportedError( - 'The extraction type must have type arguments to be extracted: ' - 'found $extractionType (${extractionType.runtimeType}) at ' - '${node.location}'); + 'The extraction type must have type arguments to be extracted: ' + 'found $extractionType (${extractionType.runtimeType}) at ' + '${node.location}', + ); } - var extractionTypeParameterNames = extractionTypeParameters - .map((p) => '${extractionType.classNode.name}.${p.name!}'); + var extractionTypeParameterNames = extractionTypeParameters.map( + (p) => '${extractionType.classNode.name}.${p.name!}', + ); var instance = node.arguments.positional.first.accept(this); var function = node.arguments.positional.last.accept(this); var extractedTypeArgs = js_ast.ArrayInitializer([ @@ -6140,8 +6789,8 @@ js.call('#.#(#, "$recipe")', [ _emitLibraryName(_rtiLibrary), _emitMemberName('evalInInstance', memberClass: _rtiClass), - instance - ]) + instance, + ]), ]); return _runtimeCall('dgcall(#, #, [])', [function, extractedTypeArgs]); } @@ -6182,8 +6831,9 @@ } if (type is! InterfaceType) { throw UnsupportedError( - 'JS_CLASS_REF only supports interface types: found $type ' - '(${type.runtimeType}) at ${node.location}'); + 'JS_CLASS_REF only supports interface types: found $type ' + '(${type.runtimeType}) at ${node.location}', + ); } return _emitTopLevelName(type.classNode); } @@ -6204,7 +6854,8 @@ // extra information recorded. js.boolean(true), _ => throw UnsupportedError( - 'Unknown JS_GET_FLAG "$value" at ${node.location}') + 'Unknown JS_GET_FLAG "$value" at ${node.location}', + ), }; } } else if (args.length == 2) { @@ -6248,8 +6899,10 @@ if (name == '_jsInstanceOf' && type is InterfaceType && type.typeArguments.isEmpty) { - return js.call('# instanceof #', - [_visitExpression(firstArg), _emitTopLevelName(type.classNode)]); + return js.call('# instanceof #', [ + _visitExpression(firstArg), + _emitTopLevelName(type.classNode), + ]); } } } @@ -6257,15 +6910,19 @@ var name = target.name.text; if (name == 'jsObjectGetPrototypeOf') { var obj = node.arguments.positional.single; - return _emitJSObjectGetPrototypeOf(_visitExpression(obj), - fullyQualifiedName: false); + return _emitJSObjectGetPrototypeOf( + _visitExpression(obj), + fullyQualifiedName: false, + ); } if (name == 'jsObjectSetPrototypeOf') { var obj = node.arguments.positional.first; var prototype = node.arguments.positional.last; return _emitJSObjectSetPrototypeOf( - _visitExpression(obj), _visitExpression(prototype), - fullyQualifiedName: false); + _visitExpression(obj), + _visitExpression(prototype), + fullyQualifiedName: false, + ); } } if (target.isExternal && @@ -6275,9 +6932,13 @@ // and factories have named parameters. assert(target.function.positionalParameters.isEmpty); return _emitObjectLiteral( - Arguments(node.arguments.positional, - types: node.arguments.types, named: node.arguments.named), - target); + Arguments( + node.arguments.positional, + types: node.arguments.types, + named: node.arguments.named, + ), + target, + ); } if (target == _coreTypes.identicalProcedure) { return _emitCoreIdenticalCall(node.arguments.positional); @@ -6298,13 +6959,18 @@ var name = target.name.text; if (name == '_getPropertyTrustType') { return js_ast.PropertyAccess( - _visitExpression(node.arguments.positional[0]), - _visitExpression(node.arguments.positional[1])); + _visitExpression(node.arguments.positional[0]), + _visitExpression(node.arguments.positional[1]), + ); } else if (name == '_setPropertyUnchecked') { - return _visitExpression(node.arguments.positional[2]) - .toAssignExpression(js_ast.PropertyAccess( - _visitExpression(node.arguments.positional[0]), - _visitExpression(node.arguments.positional[1]))); + return _visitExpression( + node.arguments.positional[2], + ).toAssignExpression( + js_ast.PropertyAccess( + _visitExpression(node.arguments.positional[0]), + _visitExpression(node.arguments.positional[1]), + ), + ); } else if (_callMethodUncheckedRegex.hasMatch(name)) { // Note that we don't lower `_callMethodTrustType`. This is because it // uses `assertInterop` checks. @@ -6316,10 +6982,12 @@ args.add(_visitExpression(node.arguments.positional[i])); } js_ast.Expression call = js_ast.Call( - js_ast.PropertyAccess( - _visitExpression(node.arguments.positional[0]), - _visitExpression(node.arguments.positional[1])), - args); + js_ast.PropertyAccess( + _visitExpression(node.arguments.positional[0]), + _visitExpression(node.arguments.positional[1]), + ), + args, + ); if (!trustType) { call = _emitCast(call, node.arguments.types[0]); } @@ -6332,8 +7000,9 @@ args.add(_visitExpression(node.arguments.positional[i])); } return _emitCast( - js_ast.New(_visitExpression(node.arguments.positional[0]), args), - node.arguments.types[0]); + js_ast.New(_visitExpression(node.arguments.positional[0]), args), + node.arguments.types[0], + ); } } @@ -6345,15 +7014,19 @@ : staticCall; } - js_ast.Expression _emitJSObjectGetPrototypeOf(js_ast.Expression obj, - {required bool fullyQualifiedName}) => + js_ast.Expression _emitJSObjectGetPrototypeOf( + js_ast.Expression obj, { + required bool fullyQualifiedName, + }) => fullyQualifiedName ? _runtimeCall('global.Object.getPrototypeOf(#)', [obj]) : js.call('Object.getPrototypeOf(#)', obj); js_ast.Expression _emitJSObjectSetPrototypeOf( - js_ast.Expression obj, js_ast.Expression prototype, - {required bool fullyQualifiedName}) => + js_ast.Expression obj, + js_ast.Expression prototype, { + required bool fullyQualifiedName, + }) => fullyQualifiedName ? _runtimeCall('global.Object.setPrototypeOf(#, #)', [obj, prototype]) : js.call('Object.setPrototypeOf(#, #)', [obj, prototype]); @@ -6366,8 +7039,9 @@ js_ast.Node _emitDebuggerCall(StaticInvocation node) { var args = node.arguments.named; var isStatement = node.parent is ExpressionStatement; - var debuggerStatement = - js_ast.DebuggerStatement().withSourceInformation(_nodeStart(node)); + var debuggerStatement = js_ast.DebuggerStatement().withSourceInformation( + _nodeStart(node), + ); if (args.isEmpty) { // Inline `debugger()` with no arguments, as a statement if possible, // otherwise as an immediately invoked function. @@ -6399,8 +7073,10 @@ : js.call('#.when', js_ast.ObjectInitializer(jsArgs)); return isStatement ? js.statement('if (#) #;', [when, debuggerStatement]) - : js.call( - '# && (() => { #; return true })()', [when, debuggerStatement]); + : js.call('# && (() => { #; return true })()', [ + when, + debuggerStatement, + ]); } /// Emits the target of a [StaticInvocation], [StaticGet], or [StaticSet]. @@ -6419,11 +7095,15 @@ ? _emitStaticMemberName(target.name.text, target) : js.string(annotationName); return js_ast.PropertyAccess( - _runtimeCall('global.#', [nativeName[0]]), memberName); + _runtimeCall('global.#', [nativeName[0]]), + memberName, + ); } } - return js_ast.PropertyAccess(_emitStaticClassName(c, isExternal), - _emitStaticMemberName(target.name.text, target)); + return js_ast.PropertyAccess( + _emitStaticClassName(c, isExternal), + _emitStaticMemberName(target.name.text, target), + ); } return _emitTopLevelName(target); } @@ -6437,12 +7117,20 @@ /// Passing [target] when applicable allows for detection of an annotation to /// omit passing type parameters and to detect if positional arguments should /// be packaged to be passed to a JavaScript using an interop call. - List<js_ast.Expression> _emitArgumentList(Arguments node, - {bool types = true, Member? target}) { + List<js_ast.Expression> _emitArgumentList( + Arguments node, { + bool types = true, + Member? target, + }) { types = types && _reifyGenericFunction(target); - var (:typeArguments, :positionalArguments, :namedArguments) = - _emitArgumentGroups(node, - isJSInterop: target != null && isJsMember(target)); + var ( + :typeArguments, + :positionalArguments, + :namedArguments, + ) = _emitArgumentGroups( + node, + isJSInterop: target != null && isJsMember(target), + ); return [ if (types && typeArguments != null) ...typeArguments, if (positionalArguments != null) ...positionalArguments, @@ -6458,8 +7146,10 @@ /// /// When [isJSInterop] is `true` the positional arguments are packaged to /// be passed to JavaScript via an interop call. - _ArgumentGroups _emitArgumentGroups(Arguments node, - {required bool isJSInterop}) { + _ArgumentGroups _emitArgumentGroups( + Arguments node, { + required bool isJSInterop, + }) { var typeArguments = node.types.isEmpty ? null : [for (var typeArgument in node.types) _emitType(typeArgument)]; @@ -6483,12 +7173,14 @@ return ( typeArguments: typeArguments, positionalArguments: positionalArguments, - namedArguments: namedArguments + namedArguments: namedArguments, ); } - js_ast.Property _emitNamedExpression(NamedExpression arg, - [bool isJsInterop = false]) { + js_ast.Property _emitNamedExpression( + NamedExpression arg, [ + bool isJsInterop = false, + ]) { var value = isJsInterop ? _assertInterop(arg.value) : arg.value; return js_ast.Property(_propertyName(arg.name), _visitExpression(value)); } @@ -6510,8 +7202,9 @@ } else { if (args.length > 2) { throw ArgumentError( - "Can't mix template args and string interpolation in JS calls: " - '`$node`'); + "Can't mix template args and string interpolation in JS calls: " + '`$node`', + ); } templateArgs = <Expression>[]; source = code.expressions.map((expression) { @@ -6548,8 +7241,10 @@ } } - assert(result is js_ast.Expression || - result is js_ast.Statement && node.parent is ExpressionStatement); + assert( + result is js_ast.Expression || + result is js_ast.Statement && node.parent is ExpressionStatement, + ); return result.withSourceInformation(_nodeStart(node)); } @@ -6572,22 +7267,29 @@ case JsGetName.OPERATOR_IS_PREFIX: return js.string(js_ast.FixedNames.operatorIsPrefix); case JsGetName.SIGNATURE_NAME: - return _runtimeCall( - '#', [js.string(js_ast.FixedNames.operatorSignature)]); + return _runtimeCall('#', [ + js.string(js_ast.FixedNames.operatorSignature), + ]); case JsGetName.RTI_NAME: return js.string(js_ast.FixedNames.rtiName); case JsGetName.FUTURE_CLASS_TYPE_NAME: return js.string( - _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.futureClass)); + _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.futureClass), + ); case JsGetName.LIST_CLASS_TYPE_NAME: return js.string( - _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.listClass)); + _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.listClass), + ); case JsGetName.RTI_FIELD_AS: - return _emitMemberName(js_ast.FixedNames.rtiAsField, - memberClass: _rtiClass); + return _emitMemberName( + js_ast.FixedNames.rtiAsField, + memberClass: _rtiClass, + ); case JsGetName.RTI_FIELD_IS: - return _emitMemberName(js_ast.FixedNames.rtiIsField, - memberClass: _rtiClass); + return _emitMemberName( + js_ast.FixedNames.rtiIsField, + memberClass: _rtiClass, + ); default: throw UnsupportedError('JsGetName has no name for "$name".'); } @@ -6614,11 +7316,13 @@ return '$enumName.$valueName'; } - JsGetName _asJsGetName(Field field) => JsGetName.values - .firstWhere((val) => val.toString() == _enumValueName(field)); + JsGetName _asJsGetName(Field field) => JsGetName.values.firstWhere( + (val) => val.toString() == _enumValueName(field), + ); - JsBuiltin _asJsBuiltin(Field field) => JsBuiltin.values - .firstWhere((val) => val.toString() == _enumValueName(field)); + JsBuiltin _asJsBuiltin(Field field) => JsBuiltin.values.firstWhere( + (val) => val.toString() == _enumValueName(field), + ); bool _isWebLibrary(Uri importUri) => importUri.isScheme('dart') && @@ -6639,8 +7343,10 @@ if (_isNull(left) || _isNull(right)) return true; // If the representation of the two types will not induce conversion in // JS then we can use == . - return !_typeRep.equalityMayConvert(left.getStaticType(_staticTypeContext), - right.getStaticType(_staticTypeContext)); + return !_typeRep.equalityMayConvert( + left.getStaticType(_staticTypeContext), + right.getStaticType(_staticTypeContext), + ); } bool _tripleEqIsIdentity(Expression left, Expression right) { @@ -6652,24 +7358,31 @@ /// Returns true if [expr] can be null. bool _isNullable(Expression expr) => _nullableInference.isNullable(expr); - js_ast.Expression _emitJSDoubleEq(List<js_ast.Expression> args, - {bool negated = false}) { + js_ast.Expression _emitJSDoubleEq( + List<js_ast.Expression> args, { + bool negated = false, + }) { var op = negated ? '# != #' : '# == #'; return js.call(op, args); } - js_ast.Expression _emitJSTripleEq(List<js_ast.Expression> args, - {bool negated = false}) { + js_ast.Expression _emitJSTripleEq( + List<js_ast.Expression> args, { + bool negated = false, + }) { var op = negated ? '# !== #' : '# === #'; return js.call(op, args); } - js_ast.Expression _emitCoreIdenticalCall(List<Expression> args, - {bool negated = false}) { + js_ast.Expression _emitCoreIdenticalCall( + List<Expression> args, { + bool negated = false, + }) { if (args.length != 2) { // Shouldn't happen in typechecked code return _runtimeCall( - 'throw(Error("compile error: calls to `identical` require 2 args")'); + 'throw(Error("compile error: calls to `identical` require 2 args")', + ); } var left = args[0]; var right = args[1]; @@ -6681,8 +7394,10 @@ return _emitJSDoubleEq(jsArgs, negated: negated); } var code = negated ? '!#' : '#'; - return js.call(code, - js_ast.Call(_emitTopLevelName(_coreTypes.identicalProcedure), jsArgs)); + return js.call( + code, + js_ast.Call(_emitTopLevelName(_coreTypes.identicalProcedure), jsArgs), + ); } /// Returns true if this [member] is a JS interop member. @@ -6699,16 +7414,15 @@ var shouldProvideRti = !isJSInteropMember(ctor) && _requiresRtiForInstantiation(ctorClass); var rti = shouldProvideRti - ? _emitType(node.constructedType, - emitJSInteropGenericClassTypeParametersAsAny: false) + ? _emitType( + node.constructedType, + emitJSInteropGenericClassTypeParametersAsAny: false, + ) : null; - var result = js_ast.New( - _emitConstructorName(node.constructedType, ctor), - [ - if (rti != null) rti, - ..._emitArgumentList(args, types: false, target: ctor) - ], - ); + var result = js_ast.New(_emitConstructorName(node.constructedType, ctor), [ + if (rti != null) rti, + ..._emitArgumentList(args, types: false, target: ctor), + ]); return node.isConst ? _canonicalizeConstObject(result) : result; } @@ -6774,8 +7488,10 @@ var rti = _requiresRtiForInstantiation(ctorClass) ? _emitType(type, emitJSInteropGenericClassTypeParametersAsAny: false) : null; - var result = js_ast.Call(_emitConstructorName(type, ctor), - [if (rti != null) rti, ..._emitArgumentList(args, types: false)]); + var result = js_ast.Call(_emitConstructorName(type, ctor), [ + if (rti != null) rti, + ..._emitArgumentList(args, types: false), + ]); return node.isConst ? _canonicalizeConstObject(result) : result; } @@ -6784,8 +7500,9 @@ if (isJSAnonymousType(ctorClass)) return _emitObjectLiteral(args, ctor); // JS interop constructor calls do not require an RTI at the call site. return js_ast.New( - _emitConstructorName(_coreTypes.nonNullableRawType(ctorClass), ctor), - _emitArgumentList(args, types: false, target: ctor)); + _emitConstructorName(_coreTypes.nonNullableRawType(ctorClass), ctor), + _emitArgumentList(args, types: false, target: ctor), + ); } InterfaceType _createMapImplType(InterfaceType type, {bool? identity}) { @@ -6820,23 +7537,31 @@ var operand = node.operand; if (operand is EqualsCall) { return _emitEqualityOperator( - operand.left, operand.interfaceTarget, operand.right, - negated: true); + operand.left, + operand.interfaceTarget, + operand.right, + negated: true, + ); } else if (operand is EqualsNull) { - return _emitCoreIdenticalCall([operand.expression, NullLiteral()], - negated: true); + return _emitCoreIdenticalCall([ + operand.expression, + NullLiteral(), + ], negated: true); } else if (operand is StaticInvocation && operand.target == _coreTypes.identicalProcedure) { - return _emitCoreIdenticalCall(operand.arguments.positional, - negated: true); + return _emitCoreIdenticalCall( + operand.arguments.positional, + negated: true, + ); } var jsOperand = _visitTest(operand); if (jsOperand is js_ast.LiteralBool) { // Flipping the value here for `!true` or `!false` allows for simpler // `if (true)` or `if (false)` detection and optimization. - return js_ast.LiteralBool(!jsOperand.value) - .withSourceInformation(jsOperand.sourceInformation) + return js_ast.LiteralBool( + !jsOperand.value, + ).withSourceInformation(jsOperand.sourceInformation) as js_ast.LiteralBool; } @@ -6889,8 +7614,10 @@ continue; } var type = e.getStaticType(_staticTypeContext).extensionTypeErasure; - if (DartTypeEquivalence(_coreTypes, ignoreTopLevelNullability: true) - .areEqual(type, _coreTypes.stringNonNullableRawType) && + if (DartTypeEquivalence( + _coreTypes, + ignoreTopLevelNullability: true, + ).areEqual(type, _coreTypes.stringNonNullableRawType) && !_isNullable(e)) { parts.add(jsExpr); } else if (_shouldCallObjectMemberHelper(e)) { @@ -6942,7 +7669,8 @@ @override js_ast.Expression visitRedirectingFactoryTearOff( - RedirectingFactoryTearOff node) { + RedirectingFactoryTearOff node, + ) { throw UnsupportedError('RedirectingFactory tear off'); } @@ -6978,7 +7706,7 @@ return js.call('#.#(#)', [ _emitType(type), _emitMemberName(js_ast.FixedNames.rtiIsField, memberClass: _rtiClass), - lhs + lhs, ]); } @@ -6987,13 +7715,20 @@ var fromExpr = node.operand; var jsFrom = _visitExpression(fromExpr); if (node.isUnchecked) return jsFrom; - return _emitCast(jsFrom, node.type, - fromStaticType: fromExpr.getStaticType(_staticTypeContext), - isTypeError: node.isTypeError); + return _emitCast( + jsFrom, + node.type, + fromStaticType: fromExpr.getStaticType(_staticTypeContext), + isTypeError: node.isTypeError, + ); } - js_ast.Expression _emitCast(js_ast.Expression value, DartType toType, - {DartType? fromStaticType, bool isTypeError = false}) { + js_ast.Expression _emitCast( + js_ast.Expression value, + DartType toType, { + DartType? fromStaticType, + bool isTypeError = false, + }) { toType = toType.extensionTypeErasure; if (_types.isTop(toType)) return value; if (fromStaticType != null) { @@ -7017,13 +7752,18 @@ // if (!isTypeError && _types.isSubtypeOf( - fromStaticType, toType, SubtypeCheckMode.withNullabilities)) { + fromStaticType, + toType, + SubtypeCheckMode.withNullabilities, + )) { return value; } if (!isTypeError && _mustBeNonNullable(toType) && - DartTypeEquivalence(_coreTypes, ignoreTopLevelNullability: true) - .areEqual(fromStaticType, toType)) { + DartTypeEquivalence( + _coreTypes, + ignoreTopLevelNullability: true, + ).areEqual(fromStaticType, toType)) { // If the underlying type is the same, we only need a null check. return _runtimeCall('nullCast(#, #)', [value, _emitType(toType)]); } @@ -7053,7 +7793,7 @@ return js.call('#.#(#)', [ _emitType(toType), _emitMemberName(js_ast.FixedNames.rtiAsField, memberClass: _rtiClass), - value + value, ]); } @@ -7096,8 +7836,10 @@ // If the type is a type literal expression in Dart code, wrap the raw // runtime type in a "Type" instance. - return js.call( - '#.createRuntimeType(#)', [_emitLibraryName(_rtiLibrary), typeRep]); + return js.call('#.createRuntimeType(#)', [ + _emitLibraryName(_rtiLibrary), + typeRep, + ]); } @override @@ -7120,48 +7862,63 @@ } js_ast.Expression _emitList( - DartType itemType, List<js_ast.Expression> items) { + DartType itemType, + List<js_ast.Expression> items, + ) { var list = js_ast.ArrayInitializer(items); // List's type parameter is default-initialized to dynamic in our runtime. if (itemType == const DynamicType()) return list; // Call `new JSArray<E>.of(list)` - var type = - InterfaceType(_jsArrayClass, Nullability.nonNullable, [itemType]); + var type = InterfaceType(_jsArrayClass, Nullability.nonNullable, [ + itemType, + ]); var arrayClass = _emitClassRef(type); var arrayRti = _emitType(type); return js.call('#.of(#, #)', [arrayClass, arrayRti, list]); } js_ast.Expression _emitConstList( - DartType elementType, List<js_ast.Expression> elements) { + DartType elementType, + List<js_ast.Expression> elements, + ) { // dart.constList helper internally depends on _interceptors.JSArray. _declareBeforeUse(_jsArrayClass); - return _runtimeCall( - 'constList(#, [#])', [_emitType(elementType), elements]); + return _runtimeCall('constList(#, [#])', [ + _emitType(elementType), + elements, + ]); } @override js_ast.Expression visitSetLiteral(SetLiteral node) { // TODO(markzipan): remove const check when we use front-end const eval if (!node.isConst) { - var type = InterfaceType( - _linkedHashSetClass, Nullability.nonNullable, [node.typeArgument]); + var type = InterfaceType(_linkedHashSetClass, Nullability.nonNullable, [ + node.typeArgument, + ]); var setClass = _emitClassRef(type); var rti = _emitType(type); if (node.expressions.isEmpty) { return js.call('#.new(#)', [setClass, rti]); } - return js.call('#.from(#, [#])', - [setClass, rti, _visitExpressionList(node.expressions)]); + return js.call('#.from(#, [#])', [ + setClass, + rti, + _visitExpressionList(node.expressions), + ]); } return _emitConstSet( - node.typeArgument, _visitExpressionList(node.expressions)); + node.typeArgument, + _visitExpressionList(node.expressions), + ); } js_ast.Expression _emitConstSet( - DartType elementType, List<js_ast.Expression> elements) { + DartType elementType, + List<js_ast.Expression> elements, + ) { return _runtimeCall('constSet(#, [#])', [_emitType(elementType), elements]); } @@ -7189,16 +7946,24 @@ } js_ast.Expression _emitConstMap( - DartType keyType, DartType valueType, List<js_ast.Expression> entries) { - return _runtimeCall('constMap(#, #, [#])', - [_emitType(keyType), _emitType(valueType), entries]); + DartType keyType, + DartType valueType, + List<js_ast.Expression> entries, + ) { + return _runtimeCall('constMap(#, #, [#])', [ + _emitType(keyType), + _emitType(valueType), + entries, + ]); } /// Returns the key used for shape lookup at runtime. /// /// See `shapes` in dart:_runtime (records.dart) for a description. String _recordShapeKey( - int positionalElementCount, Iterable<String> namedElementNames) { + int positionalElementCount, + Iterable<String> namedElementNames, + ) { var elementCount = positionalElementCount + namedElementNames.length; return '$elementCount;${namedElementNames.join(',')}'; } @@ -7215,7 +7980,7 @@ [ for (var positional in node.positional) _visitExpression(positional), for (var named in node.named) _visitExpression(named.value), - ] + ], ]); return shapeExpr; } @@ -7230,8 +7995,11 @@ // checked at runtime to ensure soundness. var expectedType = _emitType(type); var asyncLibrary = _emitLibraryName(_coreTypes.asyncLibrary); - expression = js.call('#.awaitWithTypeCheck(#, #)', - [asyncLibrary, expectedType, expression]); + expression = js.call('#.awaitWithTypeCheck(#, #)', [ + asyncLibrary, + expectedType, + expression, + ]); } return js_ast.Await(expression); } @@ -7241,7 +8009,9 @@ var fn = _emitArrowFunction(node); if (!_reifyFunctionType(node.function)) return fn; return _emitFunctionTagged( - fn, node.getStaticType(_staticTypeContext) as FunctionType); + fn, + node.getStaticType(_staticTypeContext) as FunctionType, + ); } js_ast.ArrowFun _emitArrowFunction(FunctionExpression node) { @@ -7308,12 +8078,13 @@ final isAsyncIife = asyncAnalysis.hasAwaitOrYield.contains(body); if (isAsyncIife) { final transformedFunction = _rewriteAsyncFunction( - js_ast.Fun([temp], js_ast.Block([js_ast.Return(body)])), - AsyncMarker.Async, - null, - node.getStaticType(_staticTypeContext), - functionBody: _toSourceLocation(node.fileOffset), - functionEnd: _toSourceLocation(node.fileOffset)); + js_ast.Fun([temp], js_ast.Block([js_ast.Return(body)])), + AsyncMarker.Async, + null, + node.getStaticType(_staticTypeContext), + functionBody: _toSourceLocation(node.fileOffset), + functionEnd: _toSourceLocation(node.fileOffset), + ); arrowFunction = js_ast.ArrowFun([temp], transformedFunction.body); } final call = js_ast.Call(arrowFunction, [init]); @@ -7334,19 +8105,21 @@ var arrowFunction = js_ast.ArrowFun(const [], statementBlock); final asyncAnalysis = PreTranslationAnalysis((node) { throw UnsupportedError( - 'Unknown node in block expression: $node (${node.runtimeType}, ' - '${node.sourceInformation})'); + 'Unknown node in block expression: $node (${node.runtimeType}, ' + '${node.sourceInformation})', + ); }, arrowFunction) ..analyze(); final isAsyncIife = asyncAnalysis.hasAwaitOrYield.contains(statementBlock); if (isAsyncIife) { final transformedFunction = _rewriteAsyncFunction( - js_ast.Fun(const [], statementBlock), - AsyncMarker.Async, - null, - node.getStaticType(_staticTypeContext), - functionBody: _toSourceLocation(node.fileOffset), - functionEnd: _toSourceLocation(node.fileOffset)); + js_ast.Fun(const [], statementBlock), + AsyncMarker.Async, + null, + node.getStaticType(_staticTypeContext), + functionBody: _toSourceLocation(node.fileOffset), + functionEnd: _toSourceLocation(node.fileOffset), + ); arrowFunction = js_ast.ArrowFun(const [], transformedFunction.body); } final call = js_ast.Call(arrowFunction, const []); @@ -7357,7 +8130,7 @@ js_ast.Expression visitInstantiation(Instantiation node) { return _runtimeCall('gbind(#, #)', [ _visitExpression(node.expression), - node.typeArguments.map(_emitType).toList() + node.typeArguments.map(_emitType).toList(), ]); } @@ -7367,7 +8140,8 @@ js.string(node.import.enclosingLibrary.importUri.toString()), js.string(node.import.name!), js.string( - _libraryToModule(node.import.targetLibrary, throwIfNotFound: false)) + _libraryToModule(node.import.targetLibrary, throwIfNotFound: false), + ), ]); // TODO(jmesserly): DDC loads all libraries eagerly. @@ -7378,7 +8152,7 @@ js_ast.Expression visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) => _runtimeCall('checkDeferredIsLoaded(#, #)', [ js.string(node.import.enclosingLibrary.importUri.toString()), - js.string(node.import.name!) + js.string(node.import.name!), ]); bool _reifyFunctionType(FunctionNode f) { @@ -7447,7 +8221,7 @@ if (node.target.isExternal && !isSdk) { return _runtimeCall('tearoffInterop(#, #)', [ _emitStaticTarget(node.target), - js.boolean(_isNullCheckableJsInterop(node.target)) + js.boolean(_isNullCheckableJsInterop(node.target)), ]); } } @@ -7476,16 +8250,20 @@ _constTableCache[constAliasString] = js.call('void 0'); var constAliasAccessor = _constTableCache.access(constAliasString); - var constAccessor = js.call( - '# || #.#', [constAliasAccessor, _constTable, constAliasProperty]); + var constAccessor = js.call('# || #.#', [ + constAliasAccessor, + _constTable, + constAliasProperty, + ]); _constAliasCache[node] = constAccessor; var constJs = super.visitConstant(node); var func = js_ast.Fun( - [], - js_ast.Block([ - js.statement('return # = #;', [constAliasAccessor, constJs]) - ])); + [], + js_ast.Block([ + js.statement('return # = #;', [constAliasAccessor, constJs]), + ]), + ); var accessor = js_ast.Method(constAliasProperty, func, isGetter: true); _constLazyAccessors.add(accessor); return constAccessor; @@ -7552,11 +8330,15 @@ @override js_ast.Expression visitListConstant(ListConstant node) => _emitConstList( - node.typeArgument, node.entries.map(visitConstant).toList()); + node.typeArgument, + node.entries.map(visitConstant).toList(), + ); @override js_ast.Expression visitSetConstant(SetConstant node) => _emitConstSet( - node.typeArgument, node.entries.map(visitConstant).toList()); + node.typeArgument, + node.entries.map(visitConstant).toList(), + ); @override js_ast.Expression visitRecordConstant(RecordConstant node) { @@ -7570,8 +8352,8 @@ names.isEmpty ? js.call('void 0') : js.stringArray(names), [ ...node.positional.map(visitConstant), - ...node.named.values.map(visitConstant) - ] + ...node.named.values.map(visitConstant), + ], ]); } @@ -7580,8 +8362,9 @@ _declareBeforeUse(node.classNode); var savedTypeEnvironment = _currentTypeEnvironment; if (node.classNode.typeParameters.isNotEmpty) { - _currentTypeEnvironment = - ClassTypeEnvironment(node.classNode.typeParameters); + _currentTypeEnvironment = ClassTypeEnvironment( + node.classNode.typeParameters, + ); } js_ast.Property entryToProperty(MapEntry<Reference, Constant> entry) { @@ -7593,27 +8376,40 @@ // was overridden. var symbol = cls.isEnum ? _emitMemberName(member.name.text, member: member) - : _getSymbol(_emitClassPrivateNameSymbol( - cls.enclosingLibrary, getLocalClassName(cls), member)); + : _getSymbol( + _emitClassPrivateNameSymbol( + cls.enclosingLibrary, + getLocalClassName(cls), + member, + ), + ); return js_ast.Property(symbol, constant); } var type = node.getType(_staticTypeContext); - assert(type.nullability == Nullability.nonNullable, - 'An instance constant should only ever have a non-nullable type.'); + assert( + type.nullability == Nullability.nonNullable, + 'An instance constant should only ever have a non-nullable type.', + ); var classRef = _emitClassRef(type as InterfaceType); var prototype = js.call('#.prototype', [classRef]); var properties = [ if (type.typeArguments.isNotEmpty) // Generic interface type instances require a type information tag. js_ast.Property( - _propertyName(js_ast.FixedNames.rtiName), _emitType(type)), + _propertyName(js_ast.FixedNames.rtiName), + _emitType(type), + ), for (var e in node.fieldValues.entries.toList().reversed) entryToProperty(e), ]; - var constant = _canonicalizeConstObject(_emitJSObjectSetPrototypeOf( - js_ast.ObjectInitializer(properties, multiline: true), prototype, - fullyQualifiedName: false)); + var constant = _canonicalizeConstObject( + _emitJSObjectSetPrototypeOf( + js_ast.ObjectInitializer(properties, multiline: true), + prototype, + fullyQualifiedName: false, + ), + ); _currentTypeEnvironment = savedTypeEnvironment; return constant; } @@ -7624,8 +8420,11 @@ /// This is now required for fields of constant objects that may be overridden /// within the same library. js_ast.ScopedId _emitClassPrivateNameSymbol( - Library library, String className, Member member, - [js_ast.ScopedId? id]) { + Library library, + String className, + Member member, [ + js_ast.ScopedId? id, + ]) { var name = '$className.${member.name.text}'; // Wrap the name as a symbol here so it matches what you would find at // runtime when you get all properties and symbols from an instance. @@ -7645,10 +8444,12 @@ @override js_ast.Expression visitInstantiationConstant(InstantiationConstant node) => - _canonicalizeConstObject(_runtimeCall('gbind(#, #)', [ - visitConstant(node.tearOffConstant), - node.types.map(_emitType).toList() - ])); + _canonicalizeConstObject( + _runtimeCall('gbind(#, #)', [ + visitConstant(node.tearOffConstant), + node.types.map(_emitType).toList(), + ]), + ); @override js_ast.Expression visitUnevaluatedConstant(UnevaluatedConstant node) => @@ -7667,8 +8468,10 @@ // This is here to preserve the existing behavior for the non-static // JavaScript interop (including some failing cases) but could potentially // be cleaned up as a breaking change. - return _runtimeCall( - 'dload$_replSuffix(#, #)', [jsReceiver, js.string('call')]); + return _runtimeCall('dload$_replSuffix(#, #)', [ + jsReceiver, + js.string('call'), + ]); } // Otherwise, tearoff of `call` on a function type is a no-op. return jsReceiver; @@ -7687,12 +8490,13 @@ }); var header = [ js_ast.Comment( - 'Generated by DDC, the Dart Development Compiler (to JavaScript).'), + 'Generated by DDC, the Dart Development Compiler (to JavaScript).', + ), js_ast.Comment('Version: ${io.Platform.version}'), js_ast.Comment('Module: ${_options.moduleName}'), js_ast.Comment('Flags: ${headerOptions.join(', ')}'), if (enabledExperiments.isNotEmpty) - js_ast.Comment('Experiments: ${enabledExperiments.join(', ')}') + js_ast.Comment('Experiments: ${enabledExperiments.join(', ')}'), ]; return header; } @@ -7720,7 +8524,8 @@ @override js_ast.Statement visitPatternVariableDeclaration( - PatternVariableDeclaration node) { + PatternVariableDeclaration node, + ) { // This node is internal to the front end and removed by the constant // evaluator. throw UnsupportedError('ProgramCompiler.visitPatternVariableDeclaration'); @@ -7736,13 +8541,15 @@ @override js_ast.Expression visitAuxiliaryExpression(AuxiliaryExpression node) { throw UnsupportedError( - 'Unsupported auxiliary expression $node (${node.runtimeType}).'); + 'Unsupported auxiliary expression $node (${node.runtimeType}).', + ); } @override js_ast.Statement visitAuxiliaryStatement(AuxiliaryStatement node) { throw UnsupportedError( - 'Unsupported auxiliary statement $node (${node.runtimeType}).'); + 'Unsupported auxiliary statement $node (${node.runtimeType}).', + ); } /// Adds an import mapping from [library] to [id]. @@ -7755,8 +8562,10 @@ void _setEmitIfIncrementalLibrary(Library library) { if (_incrementalMode) { - _setEmitIfIncremental(_libraryToModule(library), - libraryUriToJsIdentifier(library.importUri)); + _setEmitIfIncremental( + _libraryToModule(library), + libraryUriToJsIdentifier(library.importUri), + ); } } @@ -7778,12 +8587,17 @@ /// implement special handling of the user-defined `[]=` and `==` methods. /// /// See also [_exitFunction] and [_emitReturnStatement]. - void _enterFunction(String? name, List<js_ast.Parameter> formals, - bool Function() isLastParamMutated) { + void _enterFunction( + String? name, + List<js_ast.Parameter> formals, + bool Function() isLastParamMutated, + ) { if (name == '[]=') { - _operatorSetResultStack.add(isLastParamMutated() - ? js_ast.ScopedId((formals.last as js_ast.Identifier).name) - : formals.last as js_ast.Identifier); + _operatorSetResultStack.add( + isLastParamMutated() + ? js_ast.ScopedId((formals.last as js_ast.Identifier).name) + : formals.last as js_ast.Identifier, + ); } else { _operatorSetResultStack.add(null); } @@ -7792,7 +8606,9 @@ /// Called when finished emitting methods/functions, and must correspond to a /// previous [_enterFunction] call. js_ast.Block _exitFunction( - List<js_ast.Parameter> formals, js_ast.Block code) { + List<js_ast.Parameter> formals, + js_ast.Block code, + ) { var setOperatorResult = _operatorSetResultStack.removeLast(); if (setOperatorResult != null) { // []= methods need to return the value. We could also address this at @@ -7806,8 +8622,11 @@ // If the value parameter was mutated, then we use a temporary // variable to track the initial value formals.last = setOperatorResult; - code = js - .block('{ let # = #; #; }', [valueParam, setOperatorResult, code]); + code = js.block('{ let # = #; #; }', [ + valueParam, + setOperatorResult, + code, + ]); } } return code; @@ -7859,8 +8678,11 @@ /// define new symbols and to reference existing ones. If it's called /// multiple times with same [library] and [name], we'll allocate redundant /// top-level variables (see callers to this method). - js_ast.ScopedId _emitPrivateNameSymbol(Library library, String name, - [js_ast.ScopedId? id]) { + js_ast.ScopedId _emitPrivateNameSymbol( + Library library, + String name, [ + js_ast.ScopedId? id, + ]) { /// Initializes the JS `Symbol` for the private member [name] in [library]. /// /// If the library is in the current JS module ([_libraries] contains it), @@ -7879,17 +8701,24 @@ idName = idName.replaceAll(js_ast.invalidCharInIdentifier, '_'); var identifier = id ?? js_ast.ScopedId(idName); _addSymbol( - identifier, - _runtimeCall('privateName(#, #)', - [_emitLibraryName(library), js.string(name)])); + identifier, + _runtimeCall('privateName(#, #)', [ + _emitLibraryName(library), + js.string(name), + ]), + ); if (!_containerizeSymbols) { // TODO(vsm): Change back to `const`. // See https://github.com/dart-lang/sdk/issues/40380. - _moduleItems.add(js.statement('var # = #', [ - identifier, - _runtimeCall( - 'privateName(#, #)', [_emitLibraryName(library), js.string(name)]) - ])); + _moduleItems.add( + js.statement('var # = #', [ + identifier, + _runtimeCall('privateName(#, #)', [ + _emitLibraryName(library), + js.string(name), + ]), + ]), + ); } return identifier; } @@ -7904,14 +8733,18 @@ return symbolId; } - /// Emits an expression to set the property [nameExpr] on the class [className], - /// with [value]. + /// Emits an expression to set the property [nameExpr] on the class + /// [className], with [value]. /// /// This will use `className.name = value` if possible, otherwise it will use /// `dart.defineValue(className, name, value)`. This is required when /// `FunctionNode.prototype` already defines a getters with the same name. - js_ast.Expression _defineValueOnClass(Class c, js_ast.Expression className, - js_ast.Expression nameExpr, js_ast.Expression value) { + js_ast.Expression _defineValueOnClass( + Class c, + js_ast.Expression className, + js_ast.Expression nameExpr, + js_ast.Expression value, + ) { var args = [className, nameExpr, value]; if (nameExpr is js_ast.LiteralString) { var name = nameExpr.valueWithoutQuotes; @@ -7933,16 +8766,19 @@ var name = js.escapedString(symbolName, "'"); js_ast.Expression result; if (last.startsWith('_')) { - var nativeSymbolAccessor = - _getSymbol(_emitPrivateNameSymbol(_currentLibrary!, last)); + var nativeSymbolAccessor = _getSymbol( + _emitPrivateNameSymbol(_currentLibrary!, last), + ); result = js.call('new #.new(#, #)', [ _emitConstructorAccess(_privateSymbolType), name, - nativeSymbolAccessor + nativeSymbolAccessor, ]); } else { - result = js.call( - 'new #.new(#)', [_emitConstructorAccess(_internalSymbolType), name]); + result = js.call('new #.new(#)', [ + _emitConstructorAccess(_internalSymbolType), + name, + ]); } return _canonicalizeConstObject(result); } @@ -7987,8 +8823,12 @@ // Bootstrap the ability to create Dart library objects. var libraryProto = js_ast.ScopedId('_library'); items.add(js.statement('const # = Object.create(null)', libraryProto)); - items.add(js.statement( - 'const # = Object.create(#)', [_runtimeModule, libraryProto])); + items.add( + js.statement('const # = Object.create(#)', [ + _runtimeModule, + libraryProto, + ]), + ); items.add(js.statement('#.library = #', [_runtimeModule, libraryProto])); exports.add(js_ast.NameSpecifier(_runtimeModule)); } @@ -8007,8 +8847,12 @@ // TODO(vsm): Change back to `const`. // See https://github.com/dart-lang/sdk/issues/40380. - items.add(js.statement( - 'var # = Object.create(#.library)', [libraryId, _runtimeModule])); + items.add( + js.statement('var # = Object.create(#.library)', [ + libraryId, + _runtimeModule, + ]), + ); exports.add(js_ast.NameSpecifier(libraryId, asName: aliasId)); } @@ -8018,8 +8862,9 @@ var id = _extensionSymbolsModule; // TODO(vsm): Change back to `const`. // See https://github.com/dart-lang/sdk/issues/40380. - items.add(js - .statement('var # = Object.create(#.library)', [id, _runtimeModule])); + items.add( + js.statement('var # = Object.create(#.library)', [id, _runtimeModule]), + ); exports.add(js_ast.NameSpecifier(id)); } items.add(js_ast.ExportDeclaration(js_ast.ExportClause(exports))); @@ -8029,7 +8874,9 @@ // To bootstrap the SDK, this needs to be emitted before other code. var symbol = js_ast.ScopedId('_privateNames'); items.add(js.statement('const # = Symbol("_privateNames")', symbol)); - items.add(_runtimeStatement(r''' + items.add( + _runtimeStatement( + r''' privateName = function(library, name) { let names = library[#]; if (names == null) names = library[#] = new Map(); @@ -8037,7 +8884,10 @@ if (symbol == null) names.set(name, symbol = Symbol(name)); return symbol; } - ''', [symbol, symbol])); + ''', + [symbol, symbol], + ), + ); } return items; @@ -8053,8 +8903,10 @@ // It's either one of the libraries in this module, or it's an import. return _libraries[library] ?? - _imports.putIfAbsent(library, - () => js_ast.ScopedId(libraryUriToJsIdentifier(library.importUri))); + _imports.putIfAbsent( + library, + () => js_ast.ScopedId(libraryUriToJsIdentifier(library.importUri)), + ); } /// Emits imports into [items]. @@ -8075,9 +8927,9 @@ // Generate import directives. // - // Our import variables are temps and can get renamed. Since our renaming - // is integrated into js_ast, it is aware of this possibility and will - // generate an "as" if needed. For example: + // Our import variables are temps and can get renamed. Since our + // renaming is integrated into js_ast, it is aware of this possibility + // and will generate an "as" if needed. For example: // // import {foo} from 'foo'; // if no rename needed // import {foo as foo$} from 'foo'; // if rename was needed @@ -8085,13 +8937,15 @@ var imports = <js_ast.NameSpecifier>[]; for (var library in libraries) { if (!_incrementalMode || - usedLibraries! - .contains(libraryUriToJsIdentifier(library.importUri))) { + usedLibraries!.contains( + libraryUriToJsIdentifier(library.importUri), + )) { var alias = _jsLibraryAlias(library); if (alias != null) { var aliasId = js_ast.ScopedId(alias); imports.add( - js_ast.NameSpecifier(aliasId, asName: _imports[library])); + js_ast.NameSpecifier(aliasId, asName: _imports[library]), + ); } else { imports.add(js_ast.NameSpecifier(_imports[library])); } @@ -8110,25 +8964,36 @@ } if (!_incrementalMode || imports.isNotEmpty) { - items.add(js_ast.ImportDeclaration( - namedImports: imports, from: js.string(module, "'"))); + items.add( + js_ast.ImportDeclaration( + namedImports: imports, + from: js.string(module, "'"), + ), + ); } } }); } /// Emits extension methods into [items]. - void _emitExtensionSymbols(List<js_ast.ModuleItem> items, - {bool forceExtensionSymbols = false}) { + void _emitExtensionSymbols( + List<js_ast.ModuleItem> items, { + bool forceExtensionSymbols = false, + }) { // Initialize extension symbols _extensionSymbols.forEach((name, id) { - js_ast.Expression value = - js_ast.PropertyAccess(_extensionSymbolsModule, _propertyName(name)); + js_ast.Expression value = js_ast.PropertyAccess( + _extensionSymbolsModule, + _propertyName(name), + ); if (_isBuildingSdk) { value = js.call('# = Symbol(#)', [value, js.string('dartx.$name')]); } else if (forceExtensionSymbols) { - value = js.call( - '# || (# = Symbol(#))', [value, value, js.string('dartx.$name')]); + value = js.call('# || (# = Symbol(#))', [ + value, + value, + js.string('dartx.$name'), + ]); } // Emit hoisted extension symbols that are marked as noEmit in regular as // well as incremental mode (if needed) since they are going to be @@ -8144,7 +9009,9 @@ } if (_symbolContainer.incrementalModuleItems.contains(id)) { _setEmitIfIncremental( - _libraryToModule(_coreLibrary), _extensionSymbolsModule.name); + _libraryToModule(_coreLibrary), + _extensionSymbolsModule.name, + ); } _symbolContainer[id] = value; }); @@ -8186,8 +9053,9 @@ if (usedLibraries.isNotEmpty) { _libraries.forEach((library, libraryId) { - if (usedLibraries - .contains(libraryUriToJsIdentifier(library.importUri))) { + if (usedLibraries.contains( + libraryUriToJsIdentifier(library.importUri), + )) { var alias = _jsLibraryAlias(library); var aliasId = alias == null ? libraryId : js_ast.ScopedId(alias); var asName = alias == null ? null : libraryId; @@ -8195,14 +9063,20 @@ } }); - items.add(js_ast.ImportDeclaration( - namedImports: exports, from: js.string(module, "'"))); + items.add( + js_ast.ImportDeclaration( + namedImports: exports, + from: js.string(module, "'"), + ), + ); } } /// Emits imports and extension methods into [items]. - void _emitImportsAndExtensionSymbols(List<js_ast.ModuleItem> items, - {bool forceExtensionSymbols = false}) { + void _emitImportsAndExtensionSymbols( + List<js_ast.ModuleItem> items, { + bool forceExtensionSymbols = false, + }) { _emitImports(items); _emitExtensionSymbols(items, forceExtensionSymbols: forceExtensionSymbols); } @@ -8220,13 +9094,18 @@ // We leverage that we track which libraries have been defined via // `trackedLibraries` to query whether a library already exists. if (_options.dynamicModule) { - _moduleItems.add(js.statement('''if (# != null) { + _moduleItems.add( + js.statement( + '''if (# != null) { throw Error( "Dynamic module provides second definition for " + #); - }''', [ - _runtimeCall('getLibrary(#)', [libraryName]), - libraryName - ])); + }''', + [ + _runtimeCall('getLibrary(#)', [libraryName]), + libraryName, + ], + ), + ); } var partNames = _jsPartDebuggerNames(library); @@ -8244,9 +9123,13 @@ // library. // // See also the implementation of this API in the SDK. - _moduleItems.add(_runtimeStatement( - 'trackLibraries(#, #, #, $sourceMapLocationID)', - [js.string(name), module, partMap])); + _moduleItems.add( + _runtimeStatement('trackLibraries(#, #, #, $sourceMapLocationID)', [ + js.string(name), + module, + partMap, + ]), + ); } /// Returns an accessor for [id] via the symbol container. @@ -8284,8 +9167,11 @@ /// /// Note, this function mutates the items list and returns it as the `body` /// field of the result. - js_ast.Program _finishModule(List<js_ast.ModuleItem> items, String moduleName, - {List<js_ast.Comment> header = const []}) { + js_ast.Program _finishModule( + List<js_ast.ModuleItem> items, + String moduleName, { + List<js_ast.Comment> header = const [], + }) { // TODO(jmesserly): there's probably further consolidation we can do // between DDC's two backends, by moving more code into this method, as the // code between `startModule` and `finishModule` is very similar in both. @@ -8298,8 +9184,11 @@ // Expose the entrypoint of the dynamic module under a reserved name. // TODO(sigmund): this could use a reserved symbol from dartx. var name = _emitTopLevelName(_dynamicEntrypoint!); - _moduleItems.add(js_ast.ExportDeclaration( - js('var __dynamic_module_entrypoint__ = #', [name]))); + _moduleItems.add( + js_ast.ExportDeclaration( + js('var __dynamic_module_entrypoint__ = #', [name]), + ), + ); } // Add the module's code (produced by visiting compilation units, above) @@ -8314,7 +9203,9 @@ /// /// This will not flatten blocks that are marked as being scopes. void _copyAndFlattenBlocks( - List<js_ast.ModuleItem> result, Iterable<js_ast.ModuleItem> items) { + List<js_ast.ModuleItem> result, + Iterable<js_ast.ModuleItem> items, + ) { for (var item in items) { if (item is js_ast.Block && !item.isScope) { _copyAndFlattenBlocks(result, item.statements); @@ -8333,7 +9224,8 @@ js_ast.ScopedId _getExtensionSymbolInternal(String name) { if (!_extensionSymbols.containsKey(name)) { var id = js_ast.ScopedId( - '\$${js_ast.friendlyNameForDartOperator[name] ?? name}'); + '\$${js_ast.friendlyNameForDartOperator[name] ?? name}', + ); _extensionSymbols[name] = id; _addSymbol(id, id); } @@ -8362,13 +9254,15 @@ /// Matches against the `dart:js_util` `_callMethodUnchecked` and /// `_callMethodUncheckedTrustType` variants with 0 to 4 arguments. - static final RegExp _callMethodUncheckedRegex = - RegExp(r'^\_callMethodUnchecked(TrustType)?[0-4]'); + static final RegExp _callMethodUncheckedRegex = RegExp( + r'^\_callMethodUnchecked(TrustType)?[0-4]', + ); /// Matches against the `dart:js_util` `_callConstructorUnchecked` and /// `_callConstructorUncheckedTrustType` variants with 0 to 4 arguments. - static final RegExp _callConstructorUncheckedRegex = - RegExp(r'^\_callConstructorUnchecked[0-4]'); + static final RegExp _callConstructorUncheckedRegex = RegExp( + r'^\_callConstructorUnchecked[0-4]', + ); } bool _isInlineJSFunction(Statement? body) {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart index a4e9283..371f6ab 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart
@@ -54,7 +54,7 @@ typedef _ArgumentGroups = ({ List<js_ast.Expression>? typeArguments, List<js_ast.Expression>? positionalArguments, - List<js_ast.Property>? namedArguments + List<js_ast.Property>? namedArguments, }); /// Name used as a prefix for extension symbols and the identifier of the object @@ -147,12 +147,17 @@ var compiledLibraries = <js_ast.Program>[]; for (var library in component.libraries) { var libraryCompiler = LibraryCompiler( - component, _hierarchy, _options, _importToSummary, _summaryToModule, - coreTypes: _coreTypes, - ticker: _ticker, - symbolData: _symbolData, - hotReloadLibraryMetadata: metadata?[library], - hotReloadGeneration: repo?.generation); + component, + _hierarchy, + _options, + _importToSummary, + _summaryToModule, + coreTypes: _coreTypes, + ticker: _ticker, + symbolData: _symbolData, + hotReloadLibraryMetadata: metadata?[library], + hotReloadGeneration: repo?.generation, + ); _libraryCompilers[library] = libraryCompiler; compiledLibraries.add(libraryCompiler.emitLibrary(library)); } @@ -163,7 +168,7 @@ // Collect all extension symbols from all SDK libraries. var allSymbols = { for (var compiler in _libraryCompilers.values) - ...compiler._extensionSymbols + ...compiler._extensionSymbols, }; // Create dartx library var id = js_ast.Identifier(_extensionSymbolHolderName); @@ -171,30 +176,48 @@ for (var entry in allSymbols.entries) js.statement('# = Symbol(#);', [ js_ast.PropertyAccess(id, js.string(entry.key)), - js.string('$_extensionSymbolHolderName.${entry.key}') + js.string('$_extensionSymbolHolderName.${entry.key}'), ]), js.statement('# = #', [ js_ast.PropertyAccess(id, js.call('dartDevEmbedder.linkSymbol')), js_ast.NamedFunction( - js_ast.ScopedId('link__$_extensionSymbolHolderName'), - js_ast.Fun(const [], js_ast.Block(const []))) + js_ast.ScopedId('link__$_extensionSymbolHolderName'), + js_ast.Fun(const [], js_ast.Block(const [])), + ), ]), ]; compiledLibraries.insert( - 0, - js_ast.Program(statements, - name: _extensionSymbolHolderName, librarySelfVar: id)); + 0, + js_ast.Program( + statements, + name: _extensionSymbolHolderName, + librarySelfVar: id, + ), + ); } - return js_ast.LibraryBundle(compiledLibraries, - name: _options.moduleName, header: _generateCompilationHeader()); + return js_ast.LibraryBundle( + compiledLibraries, + name: _options.moduleName, + header: _generateCompilationHeader(), + ); } @override - js_ast.Fun emitFunctionIncremental(List<js_ast.ModuleItem> items, - Library library, Class? cls, FunctionNode functionNode, String name) { - return _libraryCompilers[library]! - ._emitFunctionIncremental(items, library, cls, functionNode, name); + js_ast.Fun emitFunctionIncremental( + List<js_ast.ModuleItem> items, + Library library, + Class? cls, + FunctionNode functionNode, + String name, + ) { + return _libraryCompilers[library]!._emitFunctionIncremental( + items, + library, + cls, + functionNode, + name, + ); } /// Creates header comments with helpful compilation information. @@ -210,12 +233,13 @@ }); var header = [ js_ast.Comment( - 'Generated by DDC, the Dart Development Compiler (to JavaScript).'), + 'Generated by DDC, the Dart Development Compiler (to JavaScript).', + ), js_ast.Comment('Version: ${io.Platform.version}'), js_ast.Comment('Module: ${_options.moduleName}'), js_ast.Comment('Flags: ${headerOptions.join(', ')}'), if (enabledExperiments.isNotEmpty) - js_ast.Comment('Experiments: ${enabledExperiments.join(', ')}') + js_ast.Comment('Experiments: ${enabledExperiments.join(', ')}'), ]; return header; } @@ -274,7 +298,7 @@ Map<VariableDeclaration, js_ast.Identifier> get variableIdentifiers => _symbolData.variableIdentifiers; - /// Identifiers for kernel variables with an analgous identifier in JS. + /// Identifiers for kernel variables with an analogous identifier in JS. /// /// [VariableDeclaration.name] is not necessarily a safe identifier for JS /// transpiled code. The same name can be used in shadowing contexts. We map @@ -514,8 +538,10 @@ final _privateNames = HashMap<Library, HashMap<String, js_ast.ScopedId>>(); /// Holds all top-level JS symbols (used for caching or indexing fields). - final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject('S', - keyToString: (js_ast.Identifier i) => i.name); + final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject( + 'S', + keyToString: (js_ast.Identifier i) => i.name, + ); /// Extension member symbols for adding Dart members to JS types. /// @@ -670,87 +696,127 @@ var jsTypeRep = JSTypeRep(types, hierarchy); var staticTypeContext = StatefulStaticTypeContext.stacked(types); return LibraryCompiler._( - ticker, - coreTypes, - coreTypes.index, - nativeTypes, - constants, - types, - hierarchy, - jsTypeRep, - NullableInference(jsTypeRep, staticTypeContext, options: options), - staticTypeContext, - options, - importToSummary, - summaryToModule, - symbolData, - hotReloadLibraryMetadata, - hotReloadGeneration ?? 0); + ticker, + coreTypes, + coreTypes.index, + nativeTypes, + constants, + types, + hierarchy, + jsTypeRep, + NullableInference(jsTypeRep, staticTypeContext, options: options), + staticTypeContext, + options, + importToSummary, + summaryToModule, + symbolData, + hotReloadLibraryMetadata, + hotReloadGeneration ?? 0, + ); } LibraryCompiler._( - this._ticker, - this._coreTypes, - LibraryIndex sdk, - this._extensionTypes, - this._constants, - this._types, - this._hierarchy, - this._typeRep, - this._nullableInference, - this._staticTypeContext, - this._options, - this._importToSummary, - this._summaryToModule, - this._symbolData, - this._hotReloadLibraryMetadata, - this._hotReloadGeneration) - : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'), + this._ticker, + this._coreTypes, + LibraryIndex sdk, + this._extensionTypes, + this._constants, + this._types, + this._hierarchy, + this._typeRep, + this._nullableInference, + this._staticTypeContext, + this._options, + this._importToSummary, + this._summaryToModule, + this._symbolData, + this._hotReloadLibraryMetadata, + this._hotReloadGeneration, + ) : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'), _privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'), _linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'), - _identityHashMapImplClass = - sdk.getClass('dart:_js_helper', 'IdentityMap'), + _identityHashMapImplClass = sdk.getClass( + 'dart:_js_helper', + 'IdentityMap', + ), _linkedHashSetClass = sdk.getClass('dart:collection', 'LinkedHashSet'), _linkedHashSetImplClass = sdk.getClass('dart:_js_helper', 'LinkedSet'), - _identityHashSetImplClass = - sdk.getClass('dart:_js_helper', 'IdentitySet'), - _assertInteropMethod = - sdk.getTopLevelProcedure('dart:_runtime', 'assertInterop'), - _asyncStartMember = - sdk.getTopLevelMember('dart:async', '_asyncStartSync'), + _identityHashSetImplClass = sdk.getClass( + 'dart:_js_helper', + 'IdentitySet', + ), + _assertInteropMethod = sdk.getTopLevelProcedure( + 'dart:_runtime', + 'assertInterop', + ), + _asyncStartMember = sdk.getTopLevelMember( + 'dart:async', + '_asyncStartSync', + ), _asyncAwaitMember = sdk.getTopLevelMember('dart:async', '_asyncAwait'), _asyncReturnMember = sdk.getTopLevelMember('dart:async', '_asyncReturn'), - _asyncRethrowMember = - sdk.getTopLevelMember('dart:async', '_asyncRethrow'), - _asyncMakeCompleterMember = - sdk.getTopLevelMember('dart:async', '_makeAsyncAwaitCompleter'), - _asyncWrapJsFunctionMember = - sdk.getTopLevelMember('dart:async', '_wrapJsFunctionForAsync'), - _syncStarMakeIterableMember = - sdk.getTopLevelMember('dart:async', '_makeSyncStarIterable'), - _syncStarIteratorCurrentMember = - sdk.getMember('dart:async', '_SyncStarIterator', '_current'), - _syncStarIteratorDatumMember = - sdk.getMember('dart:async', '_SyncStarIterator', '_datum'), - _syncStarIteratorYieldStarMember = - sdk.getMember('dart:async', '_SyncStarIterator', '_yieldStar'), - _asyncStarHelperMember = - sdk.getTopLevelMember('dart:async', '_asyncStarHelper'), - _asyncStreamOfControllerMember = - sdk.getTopLevelMember('dart:async', '_streamOfController'), + _asyncRethrowMember = sdk.getTopLevelMember( + 'dart:async', + '_asyncRethrow', + ), + _asyncMakeCompleterMember = sdk.getTopLevelMember( + 'dart:async', + '_makeAsyncAwaitCompleter', + ), + _asyncWrapJsFunctionMember = sdk.getTopLevelMember( + 'dart:async', + '_wrapJsFunctionForAsync', + ), + _syncStarMakeIterableMember = sdk.getTopLevelMember( + 'dart:async', + '_makeSyncStarIterable', + ), + _syncStarIteratorCurrentMember = sdk.getMember( + 'dart:async', + '_SyncStarIterator', + '_current', + ), + _syncStarIteratorDatumMember = sdk.getMember( + 'dart:async', + '_SyncStarIterator', + '_datum', + ), + _syncStarIteratorYieldStarMember = sdk.getMember( + 'dart:async', + '_SyncStarIterator', + '_yieldStar', + ), + _asyncStarHelperMember = sdk.getTopLevelMember( + 'dart:async', + '_asyncStarHelper', + ), + _asyncStreamOfControllerMember = sdk.getTopLevelMember( + 'dart:async', + '_streamOfController', + ), _asyncMakeAsyncStarStreamControllerMember = sdk.getTopLevelMember( - 'dart:async', '_makeAsyncStarStreamController'), - _asyncIterationMarkerYieldSingleMember = - sdk.getMember('dart:async', '_IterationMarker', 'yieldSingle'), - _asyncIterationMarkerYieldStarMember = - sdk.getMember('dart:async', '_IterationMarker', 'yieldStar'), + 'dart:async', + '_makeAsyncStarStreamController', + ), + _asyncIterationMarkerYieldSingleMember = sdk.getMember( + 'dart:async', + '_IterationMarker', + 'yieldSingle', + ), + _asyncIterationMarkerYieldStarMember = sdk.getMember( + 'dart:async', + '_IterationMarker', + 'yieldStar', + ), _asyncStreamIteratorClass = sdk.getClass('dart:async', 'StreamIterator'), _futureOrNormalizer = FutureOrNormalizer(_coreTypes), _typeRecipeGenerator = TypeRecipeGenerator(_coreTypes, _hierarchy), - _extensionIndex = - ExtensionIndex(_coreTypes, _staticTypeContext.typeEnvironment), + _extensionIndex = ExtensionIndex( + _coreTypes, + _staticTypeContext.typeEnvironment, + ), _inlineTester = BasicInlineTester(_constants), _runtimeLibrary = sdk.getLibrary('dart:_runtime'), _rtiLibrary = sdk.getLibrary('dart:_rti'), @@ -820,7 +886,8 @@ m is Field ? m.isStatic : (m is Procedure ? m.isStatic : false); if (isStatic) return; var name = js_ast.toJSIdentifier( - m.name.text.replaceAll(js_ast.invalidCharInIdentifier, '_')); + m.name.text.replaceAll(js_ast.invalidCharInIdentifier, '_'), + ); uniqueNames.add(name); }); }); @@ -836,7 +903,7 @@ _constTable, js_ast.LiteralString('_'), _constTableCache.containerId, - _constTable + _constTable, ]); _moduleItems.add(constTableDeclaration); @@ -865,8 +932,10 @@ _moduleItems.insertAll(safeDeclarationIndex, _constTableCache.emit()); if (_constLazyAccessors.isNotEmpty) { - var constTableBody = _runtimeStatement( - 'defineLazy(#, { # })', [_constTable, _constLazyAccessors]); + var constTableBody = _runtimeStatement('defineLazy(#, { # })', [ + _constTable, + _constLazyAccessors, + ]); _moduleItems.insert(_constTableInsertionIndex, constTableBody); _constLazyAccessors.clear(); } @@ -874,10 +943,12 @@ // Register the local const cache for this module so it can be cleared on a // hot restart. if (_constTableCache.isNotEmpty) { - _moduleItems.add(_runtimeCall('moduleConstCaches.set(#, #)', [ - js_ast.string(_options.moduleName), - _constTableCache.containerId - ]).toStatement()); + _moduleItems.add( + _runtimeCall('moduleConstCaches.set(#, #)', [ + js_ast.string(_options.moduleName), + _constTableCache.containerId, + ]).toStatement(), + ); } _ticker?.logMs('Added table caches'); // Add all type hierarchy rules for the interface types used in this module. @@ -894,8 +965,9 @@ var type = cls.getThisType(_coreTypes, Nullability.nonNullable); _typeRecipeGenerator.addLiveTypeAncestries(type); } - var universeClass = - _rtiLibrary.classes.firstWhere((cls) => cls.name == '_Universe'); + var universeClass = _rtiLibrary.classes.firstWhere( + (cls) => cls.name == '_Universe', + ); // Emits either an 'addRules', 'addOrUpdateRules', or 'deleteRules' // statement for a JSON-serializable [rules] made of RTI type rules. @@ -908,14 +980,16 @@ // TODO: The above assumption may not hold if a class's hierarchy // changes after a hot reload. Outdated 'addRules' invocations (during // linking) may clobber updated type rules. - js_ast.Statement emitRulesStatement(Object? rules, - {required String rulesFunction}) { + js_ast.Statement emitRulesStatement( + Object? rules, { + required String rulesFunction, + }) { var template = '#._Universe.#(#, JSON.parse(#))'; var rulesExpr = js.call(template, [ _emitLibraryName(_rtiLibrary), _emitMemberName(rulesFunction, memberClass: universeClass), _runtimeCall('typeUniverse'), - js.string(jsonEncode(rules), "'") + js.string(jsonEncode(rules), "'"), ]); return rulesExpr.toStatement(); } @@ -935,8 +1009,8 @@ // a type hierarchy was deleted or edited to extend 'Object' after hot // reload. var legacyJavaScriptObjectRecipe = _typeRecipeGenerator.interfaceTypeRecipe( - _coreTypes.index - .getClass('dart:_interceptors', 'LegacyJavaScriptObject')); + _coreTypes.index.getClass('dart:_interceptors', 'LegacyJavaScriptObject'), + ); var legacyJavaScriptObjectRules = _typeRecipeGenerator .liveInterfaceTypeRules[legacyJavaScriptObjectRecipe]; var typeRulesExceptLegacyJavaScriptObject = _typeRecipeGenerator @@ -950,23 +1024,35 @@ _typeRecipeGenerator.updateLegacyJavaScriptObjectRules; if (typeRulesExceptLegacyJavaScriptObject.isNotEmpty) { - _typeRuleLinks.add(emitRulesStatement( + _typeRuleLinks.add( + emitRulesStatement( typeRulesExceptLegacyJavaScriptObject, - rulesFunction: 'addRules')); + rulesFunction: 'addRules', + ), + ); } if (_compileForHotReload && typesThatOnlyExtendObject.isNotEmpty) { - _typeRuleLinks.add(emitRulesStatement(typesThatOnlyExtendObject.toList(), - rulesFunction: 'deleteRules')); + _typeRuleLinks.add( + emitRulesStatement( + typesThatOnlyExtendObject.toList(), + rulesFunction: 'deleteRules', + ), + ); } if (legacyJavaScriptObjectRules != null) { - _typeRuleLinks.add(emitRulesStatement({ - legacyJavaScriptObjectRecipe: legacyJavaScriptObjectRules, - }, rulesFunction: 'addOrUpdateRules')); + _typeRuleLinks.add( + emitRulesStatement({ + legacyJavaScriptObjectRecipe: legacyJavaScriptObjectRules, + }, rulesFunction: 'addOrUpdateRules'), + ); } if (legacyJavaScriptObjectMutualSubtypingRules.isNotEmpty) { - _typeRuleLinks.add(emitRulesStatement( + _typeRuleLinks.add( + emitRulesStatement( legacyJavaScriptObjectMutualSubtypingRules, - rulesFunction: 'addOrUpdateRules')); + rulesFunction: 'addOrUpdateRules', + ), + ); } var jsInteropTypeRecipes = _typeRecipeGenerator.visitedJsInteropTypeRecipes; @@ -974,17 +1060,24 @@ // Update the `LegacyJavaScriptObject` class with the type tags for all // interop types in this module. This is the quick path for simple type // tests that matches the rules encoded above. - var legacyJavaScriptObjectClass = _coreTypes.index - .getClass('dart:_interceptors', 'LegacyJavaScriptObject'); + var legacyJavaScriptObjectClass = _coreTypes.index.getClass( + 'dart:_interceptors', + 'LegacyJavaScriptObject', + ); var legacyJavaScriptObjectClassRef = _emitClassRef( - legacyJavaScriptObjectClass.getThisType( - _coreTypes, Nullability.nonNullable)); + legacyJavaScriptObjectClass.getThisType( + _coreTypes, + Nullability.nonNullable, + ), + ); var interopRecipesArray = js_ast.stringArray([ _typeRecipeGenerator.interfaceTypeRecipe(legacyJavaScriptObjectClass), - ...jsInteropTypeRecipes + ...jsInteropTypeRecipes, ]); - var jsInteropRules = _runtimeStatement('addRtiResources(#, #)', - [legacyJavaScriptObjectClassRef, interopRecipesArray]); + var jsInteropRules = _runtimeStatement('addRtiResources(#, #)', [ + legacyJavaScriptObjectClassRef, + interopRecipesArray, + ]); _typeRuleLinks.add(jsInteropRules); } @@ -995,10 +1088,12 @@ var addTypeParameterVariancesStatement = js.call(addTypeParameterVariancesTemplate, [ _emitLibraryName(_rtiLibrary), - _emitMemberName('addTypeParameterVariances', - memberClass: universeClass), + _emitMemberName( + 'addTypeParameterVariances', + memberClass: universeClass, + ), _runtimeCall('typeUniverse'), - js.string(jsonEncode(typeVariances), "'") + js.string(jsonEncode(typeVariances), "'"), ]).toStatement(); _typeRuleLinks.add(addTypeParameterVariancesStatement); } @@ -1007,15 +1102,16 @@ // eagerly with 'findType' (without normalization) to avoid infinite loops. // See normalization functions in: sdk/lib/_internal/js_shared/lib/rti.dart if (_isSdkInternalRuntime(_currentLibrary!)) { - var prerequisiteRtiTypes = [ - _coreTypes.objectNullableRawType, - ]; + var prerequisiteRtiTypes = [_coreTypes.objectNullableRawType]; prerequisiteRtiTypes.forEach((type) { var recipe = _typeRecipeGenerator .recipeInEnvironment(type, EmptyTypeEnvironment()) .recipe; - _typeRuleLinks.add(js.call('#.findType("$recipe")', - [_emitLibraryName(_rtiLibrary)]).toStatement()); + _typeRuleLinks.add( + js.call('#.findType("$recipe")', [ + _emitLibraryName(_rtiLibrary), + ]).toStatement(), + ); }); } @@ -1025,19 +1121,23 @@ // Attach the import Uri to the library object for use in error messages // and debugging. - _moduleItems.add(js.statement('#[#] = #', [ - _emitLibraryName(library), - _runtimeCall('libraryImportUri'), - js.string('${library.importUri}') - ])); + _moduleItems.add( + js.statement('#[#] = #', [ + _emitLibraryName(library), + _runtimeCall('libraryImportUri'), + js.string('${library.importUri}'), + ]), + ); // Visit directives (for exports) _emitExports(library); _ticker?.logMs('Emitted exports'); // Declare imports and extension symbols - _emitImportsAndExtensionSymbols(items, - forceExtensionSymbols: allowedNativeTest(library.importUri)); + _emitImportsAndExtensionSymbols( + items, + forceExtensionSymbols: allowedNativeTest(library.importUri), + ); _ticker?.logMs('Emitted imports and extension symbols'); // Emit the hoisted type table cache variables @@ -1045,7 +1145,10 @@ _ticker?.logMs('Emitted type table'); var compiledLibrary = _finishLibrary( - items, '${library.importUri}', _emitLibraryName(library)); + items, + '${library.importUri}', + _emitLibraryName(library), + ); _ticker?.logMs('Finished emitting module'); // Mark as finished for incremental mode, so it is safe to @@ -1064,7 +1167,9 @@ js_ast.Statement _emitLibraryLinkMethod(Library library) { var libraryName = _emitLibraryName(library); var nameExpr = js_ast.PropertyAccess( - libraryName, js.call('dartDevEmbedder.linkSymbol')); + libraryName, + js.call('dartDevEmbedder.linkSymbol'), + ); var functionName = _emitScopedId('link__${_jsLibraryName(library)}'); var parameters = const <js_ast.Parameter>[]; @@ -1082,11 +1187,13 @@ ..._defineExtensionMemberLinks, ..._nativeExtensionLinks, ..._typeRuleLinks, - // Enum extensions must be emitted after type hierachies have stabilized. - ..._enumExtensions + // Enum extensions must be emitted after type hierarchies have stabilized. + ..._enumExtensions, ]); - var function = - js_ast.NamedFunction(functionName, js_ast.Fun(parameters, body)); + var function = js_ast.NamedFunction( + functionName, + js_ast.Fun(parameters, body), + ); return js.statement('# = #', [nameExpr, function]); } @@ -1114,8 +1221,9 @@ segments = uri.pathSegments; } - var qualifiedPath = - js_ast.pathToJSIdentifier(p.withoutExtension(segments.join('/'))); + var qualifiedPath = js_ast.pathToJSIdentifier( + p.withoutExtension(segments.join('/')), + ); return qualifiedPath == _jsLibraryName(library) ? null : qualifiedPath; } @@ -1163,8 +1271,10 @@ var moduleName = _summaryToModule[summary]; if (moduleName == null) { if (throwIfNotFound) { - throw StateError('Could not find module name for library "$library" ' - 'from component "$summary".'); + throw StateError( + 'Could not find module name for library "$library" ' + 'from component "$summary".', + ); } return ''; } @@ -1181,8 +1291,10 @@ if (_isSdkInternalRuntime(library)) { // Add embedded globals. _moduleItems.add( - _runtimeCall('typeUniverse = #', [js_ast.createRtiUniverse()]) - .toStatement()); + _runtimeCall('typeUniverse = #', [ + js_ast.createRtiUniverse(), + ]).toStatement(), + ); // `dart:_runtime` uses a different order for bootstrapping. // // Functions are first because we use them to associate type info @@ -1204,8 +1316,11 @@ // serves as a signal to V8 that the members of the library should get // optimized for fast lookup. // Do not remove without testing for performance regressions. - _moduleItems.add(js.statement( - '(function() {}).prototype = #', [_libraries[_currentLibrary!]])); + _moduleItems.add( + js.statement('(function() {}).prototype = #', [ + _libraries[_currentLibrary!], + ]), + ); _staticTypeContext.leaveLibrary(_currentLibrary!); } @@ -1223,8 +1338,13 @@ if (node is Procedure && node.name.text == 'main') { // Don't allow redefining names from this library. var name = _emitTopLevelName(node); - _moduleItems.add(js.statement( - '#.# = #;', [_emitLibraryName(library), name.selector, name])); + _moduleItems.add( + js.statement('#.# = #;', [ + _emitLibraryName(library), + name.selector, + name, + ]), + ); } } @@ -1257,7 +1377,9 @@ // (see [_emitMixinStatement]). if (c.isMixinDeclaration && !c.isMixinClass) { _mixinSuperclassCache.putIfAbsent( - c, () => _emitScopedId(getLocalClassName(c.superclass!))); + c, + () => _emitScopedId(getLocalClassName(c.superclass!)), + ); } // Mixins are unrolled in _defineClass. @@ -1286,15 +1408,21 @@ static js_ast.Identifier _emitIdentifier(String name) => js_ast.Identifier(js_ast.toJSIdentifier(name)); - static js_ast.ScopedId _emitScopedId(String name, - {bool needsCapture = false}) => + static js_ast.ScopedId _emitScopedId( + String name, { + bool needsCapture = false, + }) => js_ast.ScopedId(js_ast.toJSIdentifier(name), needsCapture: needsCapture); js_ast.Statement _emitClassDeclaration(Class c) { var className = _emitTopLevelNameNoExternalInterop(c); var savedClassProperties = _classProperties; - _classProperties = - ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, c); + _classProperties = ClassPropertyModel.build( + _types, + _extensionTypes, + _virtualFields, + c, + ); var body = <js_ast.Statement>[]; @@ -1307,7 +1435,11 @@ // assign directly to [virtualField]. If the latter, copy the old // variable to [virtualField]. var symbol = _emitClassPrivateNameSymbol( - c.enclosingLibrary, getLocalClassName(c), field, virtualField); + c.enclosingLibrary, + getLocalClassName(c), + field, + virtualField, + ); if (symbol != virtualField) { _addSymbol(virtualField, _getSymbolValue(symbol)); if (!_containerizeSymbols) { @@ -1325,16 +1457,19 @@ // can tag them during the delta diff phase. if (member.isStatic && _reifyTearoff(member) && !member.isExternal) { var propertyAccessor = _emitStaticTarget(member); - var result = js.call( - '#.#', [propertyAccessor.receiver, propertyAccessor.selector]); + var result = js.call('#.#', [ + propertyAccessor.receiver, + propertyAccessor.selector, + ]); // We only need to tag static functions that are torn off at // compile-time. We attach these at late so tearoffs have access to // their types. - var reifiedType = - member.function.computeThisFunctionType(Nullability.nonNullable); + var reifiedType = member.function.computeThisFunctionType( + Nullability.nonNullable, + ); jsStaticMethodTypeTags.add( - _emitFunctionTagged(result, reifiedType, asLazy: true) - .toStatement()); + _emitFunctionTagged(result, reifiedType, asLazy: true).toStatement(), + ); } } @@ -1378,10 +1513,14 @@ var implementedRecipes = [ name, for (var type in transitiveImplementedTypes(c)) - _typeRecipeGenerator.interfaceTypeRecipe(type.classNode) + _typeRecipeGenerator.interfaceTypeRecipe(type.classNode), ]; - body.add(_runtimeStatement('addRtiResources(#, #)', - [className, js_ast.stringArray(implementedRecipes)])); + body.add( + _runtimeStatement('addRtiResources(#, #)', [ + className, + js_ast.stringArray(implementedRecipes), + ]), + ); _emitClassSignature(c, className, body); _initExtensionSymbols(c); if (c.isMixinClass || c.isLegacyMixinEligible(_coreTypes)) { @@ -1392,8 +1531,10 @@ var typeFormals = c.typeParameters; if (typeFormals.isNotEmpty) { - var genericClassStmts = - _defineGenericClass(typeFormals, js_ast.Statement.from(body)); + var genericClassStmts = _defineGenericClass( + typeFormals, + js_ast.Statement.from(body), + ); body = [...genericClassStmts]; } @@ -1442,13 +1583,17 @@ c.fields.where((f) => f.isStatic && !f.isExternal).toList(); var staticFieldNames = Set.of(staticFields.map((f) => f.name)); var staticSetters = c.procedures.where( - (p) => p.isStatic && p.isAccessor && staticFieldNames.contains(p.name)); + (p) => p.isStatic && p.isAccessor && staticFieldNames.contains(p.name), + ); var members = [...staticFields, ...staticSetters]; if (members.isNotEmpty) { - nonExternalProperties.addAll(_emitLazyMembers( + nonExternalProperties.addAll( + _emitLazyMembers( _emitTopLevelNameNoExternalInterop(c), members, - (n) => _emitStaticMemberName(n.name.text))); + (n) => _emitStaticMemberName(n.name.text), + ), + ); } // Avoid unnecessary code emission if there are no members we care about. @@ -1458,8 +1603,10 @@ var body = _emitClassStatement(c, className, null, nonExternalProperties); var typeFormals = c.typeParameters; if (typeFormals.isNotEmpty) { - var genericClassStmts = - _defineGenericClass(typeFormals, js_ast.Statement.from(body)); + var genericClassStmts = _defineGenericClass( + typeFormals, + js_ast.Statement.from(body), + ); body = genericClassStmts; } return js_ast.Statement.from(body); @@ -1469,19 +1616,19 @@ /// Emits a generic class with additional initialization logic. List<js_ast.Statement> _defineGenericClass( - List<TypeParameter> formals, js_ast.Statement body) { + List<TypeParameter> formals, + js_ast.Statement body, + ) { assert(formals.isNotEmpty); - return [ - ..._typeTable.dischargeFreeTypes(formals), - body, - ]; + return [..._typeTable.dischargeFreeTypes(formals), body]; } List<js_ast.Statement> _emitClassStatement( - Class c, - js_ast.Expression className, - js_ast.Expression? heritage, - List<js_ast.Property> properties) { + Class c, + js_ast.Expression className, + js_ast.Expression? heritage, + List<js_ast.Property> properties, + ) { var localClassName = getLocalClassName(c); var classIdentifier = _emitScopedId(localClassName); var classDefIdentifier = _emitScopedId('_$localClassName'); @@ -1492,11 +1639,16 @@ if (_options.emitDebugSymbols) classIdentifiers[c] = classIdentifier; if (heritage != null) { if (referencesSuperKeyword) { - _classExtendsLinks.add(_runtimeStatement( - 'classExtends(#, #)', [classDefIdentifier, heritage])); + _classExtendsLinks.add( + _runtimeStatement('classExtends(#, #)', [ + classDefIdentifier, + heritage, + ]), + ); } - _classExtendsLinks - .add(_runtimeStatement('classExtends(#, #)', [className, heritage])); + _classExtendsLinks.add( + _runtimeStatement('classExtends(#, #)', [className, heritage]), + ); } var classExpr = js_ast.ClassExpression(classIdentifier, null, properties); var libraryExpr = (className as js_ast.PropertyAccess).receiver; @@ -1504,12 +1656,18 @@ return referencesSuperKeyword ? [ js.statement('let # = #;', [classDefIdentifier, classExpr]), - _runtimeStatement('declareClass(#, #, #)', - [libraryExpr, propertyExpr, classDefIdentifier]) + _runtimeStatement('declareClass(#, #, #)', [ + libraryExpr, + propertyExpr, + classDefIdentifier, + ]), ] : [ - _runtimeStatement( - 'declareClass(#, #, #)', [libraryExpr, propertyExpr, classExpr]) + _runtimeStatement('declareClass(#, #, #)', [ + libraryExpr, + propertyExpr, + classExpr, + ]), ]; } @@ -1541,11 +1699,12 @@ /// unnecessary class, but for now, this lets us get the right semantics with /// minimal compiler and runtime changes. void _emitMixinStatement( - Class c, - js_ast.Expression className, - js_ast.Expression heritage, - List<js_ast.Property> properties, - List<js_ast.Statement> body) { + Class c, + js_ast.Expression className, + js_ast.Expression heritage, + List<js_ast.Property> properties, + List<js_ast.Statement> body, + ) { var staticProperties = properties.where((m) => m.isStatic).toList(); var instanceProperties = properties.where((m) => !m.isStatic).toList(); @@ -1555,8 +1714,11 @@ ? className : _emitScopedId(getLocalClassName(c)); - var mixinMemberClass = - js_ast.ClassExpression(classId, superclassId, instanceProperties); + var mixinMemberClass = js_ast.ClassExpression( + classId, + superclassId, + instanceProperties, + ); js_ast.Node arrowFnBody = mixinMemberClass; var extensionInit = <js_ast.Statement>[]; @@ -1571,25 +1733,33 @@ arrowFnBody = js_ast.Block(extensionInit); } - body.add(js.statement('#[#] = #', [ - className, - _runtimeCall('mixinOn'), - js_ast.ArrowFun([superclassId], arrowFnBody) - ])); + body.add( + js.statement('#[#] = #', [ + className, + _runtimeCall('mixinOn'), + js_ast.ArrowFun([superclassId], arrowFnBody), + ]), + ); } /// Emits code required to represent [c] as a series of statements in [body]. /// /// [properties] holds methods, fields, or properties in [c]. - void _defineClass(Class c, js_ast.Expression className, - List<js_ast.Property> properties, List<js_ast.Statement> body) { + void _defineClass( + Class c, + js_ast.Expression className, + List<js_ast.Property> properties, + List<js_ast.Statement> body, + ) { if (c == _coreTypes.objectClass) { body.addAll(_emitClassStatement(c, className, null, properties)); return; } - js_ast.Expression emitClassRef(InterfaceType t, - {bool resolvedFromEmbedder = false}) { + js_ast.Expression emitClassRef( + InterfaceType t, { + bool resolvedFromEmbedder = false, + }) { return _emitJSInterop(t.classNode) ?? _emitClassRef(t, resolvedFromEmbedder: resolvedFromEmbedder); } @@ -1613,8 +1783,12 @@ var hasUnnamedSuper = _hasUnnamedInheritedConstructor(superclass); - void emitMixinConstructors(js_ast.Expression className, - Class mixinSuperclass, Class mixinClass, InterfaceType mixin) { + void emitMixinConstructors( + js_ast.Expression className, + Class mixinSuperclass, + Class mixinClass, + InterfaceType mixin, + ) { for (var ctor in mixinSuperclass.constructors) { var savedUri = _currentUri; _currentUri = ctor.enclosingClass.fileUri; @@ -1622,12 +1796,12 @@ var sharedParams = _emitParameters(ctor.function, isForwarding: true); var mixinConstructorParams = [ if (_requiresRtiForInstantiation(mixinSuperclass)) _rtiParam, - ...sharedParams + ...sharedParams, ]; var superConstructorArgs = [ if (_requiresRtiForInstantiation(ctor.enclosingClass)) js_ast.LiteralNull(), - ...sharedParams + ...sharedParams, ]; js_ast.Statement? mixinCtor; @@ -1649,11 +1823,21 @@ if (mixinCtor != null) mixinCtor, if (name != '' || hasUnnamedSuper) _emitSuperConstructorCall( - ctor, className, name, superConstructorArgs), + ctor, + className, + name, + superConstructorArgs, + ), ]; // TODO(nshahan) Record the name for this constructor in memberNames. - body.add(_addConstructorToClass(c, className, _constructorName(name), - js_ast.Fun(mixinConstructorParams, js_ast.Block(ctorBody)))); + body.add( + _addConstructorToClass( + c, + className, + _constructorName(name), + js_ast.Fun(mixinConstructorParams, js_ast.Block(ctorBody)), + ), + ); _currentUri = savedUri; } } @@ -1665,8 +1849,10 @@ var baseClass = emitClassRef(supertype); // The SDK is never hot reloaded, so we can avoid the overhead of // resolving their classes through the embedder. - var embedderResolvedBaseClass = - emitClassRef(supertype, resolvedFromEmbedder: !_isBuildingSdk); + var embedderResolvedBaseClass = emitClassRef( + supertype, + resolvedFromEmbedder: !_isBuildingSdk, + ); // TODO(jmesserly): we need to unroll kernel mixins because the synthetic // classes lack required synthetic members, such as constructors. @@ -1681,12 +1867,16 @@ // Collect all forwarding stub members from anonymous mixins classes. // These can contain covariant parameter checks that need to be applied. var savedClassProperties = _classProperties; - _classProperties = - ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, m); + _classProperties = ClassPropertyModel.build( + _types, + _extensionTypes, + _virtualFields, + m, + ); var forwardingMembers = { for (var procedure in m.procedures) if (procedure.isForwardingStub && !procedure.isAbstract) - procedure.name.text: procedure + procedure.name.text: procedure, }; // Mixin applications can introduce their own reference to the type // parameters from the class being mixed in and their use can appear in @@ -1721,31 +1911,39 @@ // workaround for a now-resolved Chrome issue. However, a side effect of // this operation is that mixin IDs are renamed by the local visitor. We // can remove this hoisting after we give mixins unique names. - body.add(js.statement('let # = #', [ - mixinId, - _runtimeCall('declareClass(#, #, #)', [ - _emitLibraryName(_currentLibrary!), - js.string(mixinId.name), - js_ast.ClassExpression( - _emitScopedId('${mixinId.name}\$'), - null, - forwardingMethodStubs, - ) - ]) - ])); + body.add( + js.statement('let # = #', [ + mixinId, + _runtimeCall('declareClass(#, #, #)', [ + _emitLibraryName(_currentLibrary!), + js.string(mixinId.name), + js_ast.ClassExpression( + _emitScopedId('${mixinId.name}\$'), + null, + forwardingMethodStubs, + ), + ]), + ]), + ); - _classExtendsLinks.add(_runtimeStatement( - 'classExtends(#, #)', [mixinId, embedderResolvedBaseClass])); + _classExtendsLinks.add( + _runtimeStatement('classExtends(#, #)', [ + mixinId, + embedderResolvedBaseClass, + ]), + ); emitMixinConstructors(mixinId, superclass, mixinClass, mixinType); hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(mixinClass); var mixinTargetLabel = js.string(fullyResolvedMixinClassLabel(m)); // The SDK is never hot reloaded, so we can avoid the overhead of // resolving their classes through the embedder. - _mixinApplicationLinks.add(_runtimeStatement('applyMixin(#, #, #)', [ - mixinId, - emitClassRef(mixinType, resolvedFromEmbedder: !_isBuildingSdk), - mixinTargetLabel - ])); + _mixinApplicationLinks.add( + _runtimeStatement('applyMixin(#, #, #)', [ + mixinId, + emitClassRef(mixinType, resolvedFromEmbedder: !_isBuildingSdk), + mixinTargetLabel, + ]), + ); baseClass = mixinId; embedderResolvedBaseClass = mixinId; } @@ -1753,8 +1951,14 @@ if (c.isMixinDeclaration && !c.isMixinClass) { _emitMixinStatement(c, className, baseClass, properties, body); } else { - body.addAll(_emitClassStatement( - c, className, embedderResolvedBaseClass, properties)); + body.addAll( + _emitClassStatement( + c, + className, + embedderResolvedBaseClass, + properties, + ), + ); } _classEmittingExtends = savedTopLevelClass; @@ -1762,7 +1966,9 @@ /// Defines all constructors for this class as ES5 constructors. List<js_ast.Statement> _defineConstructors( - Class c, js_ast.Expression className) { + Class c, + js_ast.Expression className, + ) { var body = <js_ast.Statement>[]; if (c.isAnonymousMixin) { // We already handled this when we defined the class. @@ -1779,7 +1985,9 @@ var constructorName = _constructorName(ctor.name.text); memberNames[ctor] = constructorName.valueWithoutQuotes; addConstructor( - constructorName, _emitConstructor(ctor, fields, className)); + constructorName, + _emitConstructor(ctor, fields, className), + ); } // If classElement has only factory constructors, and it can be mixed in, @@ -1787,19 +1995,22 @@ // mixins. if (_usesMixinNew(c)) { body.add( - js.statement('(#[#] = function() { # }).prototype = #.prototype;', [ - className, - _runtimeCall('mixinNew'), - [_initializeFields(fields)], - className - ])); + js.statement('(#[#] = function() { # }).prototype = #.prototype;', [ + className, + _runtimeCall('mixinNew'), + [_initializeFields(fields)], + className, + ]), + ); } return body; } void _emitDartSymbols( - Iterable<js_ast.ScopedId> vars, List<js_ast.ModuleItem> body) { + Iterable<js_ast.ScopedId> vars, + List<js_ast.ModuleItem> body, + ) { for (var id in vars) { body.add(js.statement('const # = Symbol(#)', [id, js.string(id.name)])); } @@ -1807,7 +2018,9 @@ void _emitSuperHelperSymbols(List<js_ast.Statement> body) { _emitDartSymbols( - _superHelpers.values.map((m) => m.name as js_ast.ScopedId), body); + _superHelpers.values.map((m) => m.name as js_ast.ScopedId), + body, + ); _superHelpers.clear(); } @@ -1825,17 +2038,21 @@ /// If a concrete class implements one of our extensions, we might need to /// add forwarders. void _defineExtensionMembers( - js_ast.Expression className, List<js_ast.Statement> body) { + js_ast.Expression className, + List<js_ast.Statement> body, + ) { void emitExtensions(String helperName, Iterable<String> extensions) { if (extensions.isEmpty) return; var names = extensions .map((e) => _propertyName(js_ast.memberNameForDartMember(e))) .toList(); - body.add(_runtimeStatement('#(#, #)', [ - helperName, - className, - js_ast.ArrayInitializer(names, multiline: names.length > 4) - ])); + body.add( + _runtimeStatement('#(#, #)', [ + helperName, + className, + js_ast.ArrayInitializer(names, multiline: names.length > 4), + ]), + ); } var props = _classProperties!; @@ -1845,10 +2062,14 @@ /// Emit the signature on the class recording the runtime type information void _emitClassSignature( - Class c, js_ast.Expression className, List<js_ast.Statement> body) { + Class c, + js_ast.Expression className, + List<js_ast.Statement> body, + ) { var savedTypeEnvironment = _currentTypeEnvironment; - _currentTypeEnvironment = - RtiTypeEnvironment(_currentTypeEnvironment.classTypeParameters); + _currentTypeEnvironment = RtiTypeEnvironment( + _currentTypeEnvironment.classTypeParameters, + ); var savedClass = _classEmittingSignatures; _classEmittingSignatures = c; @@ -1860,23 +2081,26 @@ var proto = c == _coreTypes.objectClass ? js.call('Object.create(null)') : _runtimeCall('get${name}s(#)', [ - _emitJSObjectGetPrototypeOf(className, fullyQualifiedName: true) + _emitJSObjectGetPrototypeOf( + className, + fullyQualifiedName: true, + ), ]); setSignature = _runtimeStatement('set${name}Signature(#, () => #)', [ className, _emitJSObjectSetPrototypeOf( - js_ast.ObjectInitializer(elements, - multiline: elements.length > 1), - proto, - fullyQualifiedName: true) + js_ast.ObjectInitializer(elements, multiline: elements.length > 1), + proto, + fullyQualifiedName: true, + ), ]); } else { // TODO(40273) Only tagging with the names of static members until the // debugger consumes signature information from symbol files. setSignature = _runtimeStatement('set${name}Signature(#, () => #)', [ className, - js_ast.ArrayInitializer(elements.map((e) => e.name).toList()) + js_ast.ArrayInitializer(elements.map((e) => e.name).toList()), ]); } @@ -1884,22 +2108,32 @@ } js_ast.Expression emitClassFieldSignature(Field field, Class fromClass) { - var fieldType = - _typeFromClass(field.type, field.enclosingClass!, fromClass) - .extensionTypeErasure; + var fieldType = _typeFromClass( + field.type, + field.enclosingClass!, + fromClass, + ).extensionTypeErasure; var uri = fieldType is InterfaceType ? _cacheUri( - _jsLibraryDebuggerName(fieldType.classNode.enclosingLibrary)) + _jsLibraryDebuggerName(fieldType.classNode.enclosingLibrary), + ) : null; var isConst = js.boolean(field.isConst); var isFinal = js.boolean(field.isFinal); var type = _emitType(fieldType); var typeResolver = js_ast.ArrowFun([_rtiParam], type); return uri == null - ? js('{type: #, isConst: #, isFinal: #}', - [typeResolver, isConst, isFinal]) - : js('{type: #, isConst: #, isFinal: #, libraryUri: #}', - [typeResolver, isConst, isFinal, uri]); + ? js('{type: #, isConst: #, isFinal: #}', [ + typeResolver, + isConst, + isFinal, + ]) + : js('{type: #, isConst: #, isFinal: #, libraryUri: #}', [ + typeResolver, + isConst, + isFinal, + uri, + ]); } var extMethods = _classProperties!.extensionMethods; @@ -1954,19 +2188,25 @@ // emit a signature on this class. Otherwise we will inherit the // signature from the superclass. var memberOverride = c.superclass != null - ? _hierarchy.getDispatchTarget(c.superclass!, member.name, - setter: member.isSetter) + ? _hierarchy.getDispatchTarget( + c.superclass!, + member.name, + setter: member.isSetter, + ) : null; var needsSignature = memberOverride == null || reifiedType != _memberRuntimeType(memberOverride, c); - var memberName = _declareMemberName(member, - useExtension: _isObjectMethodTearoff(member.name.text)); + var memberName = _declareMemberName( + member, + useExtension: _isObjectMethodTearoff(member.name.text), + ); if (!member.isAccessor) { var immediateTarget = js.string(fullyResolvedTargetLabel(member)); - methodsImmediateTarget - .add(js_ast.Property(memberName, immediateTarget)); + methodsImmediateTarget.add( + js_ast.Property(memberName, immediateTarget), + ); } if (needsSignature) { @@ -1977,9 +2217,11 @@ // library internals and should not be included in the accessible // signatures. if (c == _jsArrayClass && name == 'arrayRti') continue; - type = _emitType(member.isGetter - ? reifiedType.returnType - : reifiedType.positionalParameters[0]); + type = _emitType( + member.isGetter + ? reifiedType.returnType + : reifiedType.positionalParameters[0], + ); } else { type = _emitType(reifiedType); if (!member.isStatic && reifiedType.typeParameters.isNotEmpty) { @@ -1989,7 +2231,7 @@ // use at runtime. var defaultTypeArgs = js_ast.ArrayInitializer([ for (var parameter in reifiedType.typeParameters) - _emitType(parameter.defaultType) + _emitType(parameter.defaultType), ]); var typeResolver = js_ast.ArrowFun([_rtiParam], defaultTypeArgs); var property = js_ast.Property(memberName, typeResolver); @@ -2001,7 +2243,9 @@ // TODO(52867): Cleanup default type argument duplication. if (extMethods.contains(name) || extAccessors.contains(name)) { var property = js_ast.Property( - _declareMemberName(member, useExtension: true), typeResolver); + _declareMemberName(member, useExtension: true), + typeResolver, + ); instanceMethodsDefaultTypeArgs.add(property); } } @@ -2015,7 +2259,9 @@ // TODO(52867): Cleanup signature duplication. var typeResolver = js_ast.ArrowFun([_rtiParam], type); var property = js_ast.Property( - _declareMemberName(member, useExtension: true), typeResolver); + _declareMemberName(member, useExtension: true), + typeResolver, + ); signatures.add(property); } } @@ -2031,8 +2277,12 @@ emitSignature('Setter', instanceSetters); emitSignature('StaticGetter', staticGetters); emitSignature('StaticSetter', staticSetters); - body.add(_runtimeStatement('setLibraryUri(#, #)', - [className, _cacheUri(_jsLibraryDebuggerName(c.enclosingLibrary))])); + body.add( + _runtimeStatement('setLibraryUri(#, #)', [ + className, + _cacheUri(_jsLibraryDebuggerName(c.enclosingLibrary)), + ]), + ); var instanceFields = <js_ast.Property>[]; var staticFields = <js_ast.Property>[]; @@ -2070,36 +2320,48 @@ var fComputed = f.computeThisFunctionType(Nullability.nonNullable); var fComputedNamedByName = { for (NamedType namedParameter in fComputed.namedParameters) - namedParameter.name: namedParameter + namedParameter.name: namedParameter, }; DartType reifyParameter( - VariableDeclaration parameter, DartType fComputedParameter) => + VariableDeclaration parameter, + DartType fComputedParameter, + ) => isCovariantParameter(parameter) ? _coreTypes.objectNullableRawType : fComputedParameter; NamedType reifyNamedParameter( - VariableDeclaration parameter, NamedType fComputedNamedParameter) { + VariableDeclaration parameter, + NamedType fComputedNamedParameter, + ) { assert(parameter.name == fComputedNamedParameter.name); - return NamedType(parameter.name!, - reifyParameter(parameter, fComputedNamedParameter.type)); + return NamedType( + parameter.name!, + reifyParameter(parameter, fComputedNamedParameter.type), + ); } // TODO(jmesserly): do covariant type parameter bounds also need to be // reified as `Object`? result = FunctionType( - List<DartType>.generate( - f.positionalParameters.length, - (index) => reifyParameter(f.positionalParameters[index], - fComputed.positionalParameters[index])), - f.returnType, - Nullability.nonNullable, - namedParameters: List<NamedType>.generate( - f.namedParameters.length, - (index) => reifyNamedParameter(f.namedParameters[index], - fComputedNamedByName[f.namedParameters[index].name]!)) - ..sort(), - typeParameters: fComputed.typeParameters, - requiredParameterCount: f.requiredParameterCount); + List<DartType>.generate( + f.positionalParameters.length, + (index) => reifyParameter( + f.positionalParameters[index], + fComputed.positionalParameters[index], + ), + ), + f.returnType, + Nullability.nonNullable, + namedParameters: List<NamedType>.generate( + f.namedParameters.length, + (index) => reifyNamedParameter( + f.namedParameters[index], + fComputedNamedByName[f.namedParameters[index].name]!, + ), + )..sort(), + typeParameters: fComputed.typeParameters, + requiredParameterCount: f.requiredParameterCount, + ); } return _typeFromClass(result, member.enclosingClass!, fromClass) as FunctionType; @@ -2108,26 +2370,31 @@ DartType _typeFromClass(DartType type, Class superclass, Class subclass) { if (identical(superclass, subclass)) return type; return Substitution.fromSupertype( - _hierarchy.getClassAsInstanceOf(subclass, superclass)!) - .substituteType(type); + _hierarchy.getClassAsInstanceOf(subclass, superclass)!, + ).substituteType(type); } js_ast.Expression _emitConstructor( - Constructor node, List<Field> fields, js_ast.Expression className) { + Constructor node, + List<Field> fields, + js_ast.Expression className, + ) { var savedUri = _currentUri; _currentUri = node.fileUri; _staticTypeContext.enterMember(node); var savedTypeEnvironment = _currentTypeEnvironment; - _currentTypeEnvironment = - ClassTypeEnvironment(node.enclosingClass.typeParameters); + _currentTypeEnvironment = ClassTypeEnvironment( + node.enclosingClass.typeParameters, + ); var params = <js_ast.Parameter>[]; // Generic class constructors accept their RTI as their first argument. params.addAll(_emitParameters(node.function)); var body = _withCurrentFunction( - node.function, - () => _superDisallowed( - () => _emitConstructorBody(node, fields, className))); + node.function, + () => + _superDisallowed(() => _emitConstructorBody(node, fields, className)), + ); var end = _nodeEnd(node.fileEndOffset); _currentUri = savedUri; @@ -2136,7 +2403,7 @@ var constructor = js_ast.Fun([ if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam, - ...params + ...params, ], js_ast.Block(body)) ..sourceInformation = end; @@ -2165,12 +2432,14 @@ // Only set the rti if there isn't one already. This avoids superclasses // overwriting the value already set by a subclass. var rtiProperty = _propertyName(js_ast.FixedNames.rtiName); - body.add(js.statement('this.# = this.# || # || #', [ - rtiProperty, - rtiProperty, - _rtiParam, - _runtimeCall('getReifiedType(this)') - ])); + body.add( + js.statement('this.# = this.# || # || #', [ + rtiProperty, + rtiProperty, + _rtiParam, + _runtimeCall('getReifiedType(this)'), + ]), + ); } // Redirecting constructors are not allowed to have conventional @@ -2256,7 +2525,9 @@ } js_ast.Statement _emitRedirectingConstructor( - List<Initializer> initializers, js_ast.Expression className) { + List<Initializer> initializers, + js_ast.Expression className, + ) { var jsInitializers = <js_ast.Statement>[]; for (var init in initializers) { if (init is LocalInitializer) { @@ -2274,8 +2545,8 @@ _constructorName(init.target.name.text), [ if (rtiParam != null) rtiParam, - ..._emitArgumentList(init.arguments, types: false) - ] + ..._emitArgumentList(init.arguments, types: false), + ], ]); jsInitializers.add(initializer); } @@ -2284,7 +2555,10 @@ } js_ast.Statement? _emitSuperConstructorCallIfNeeded( - Class c, js_ast.Expression className, SuperInitializer? superInit) { + Class c, + js_ast.Expression className, + SuperInitializer? superInit, + ) { if (c == _coreTypes.objectClass) return null; Constructor ctor; @@ -2303,7 +2577,7 @@ : null; args = [ if (rti != null) rti, - ..._emitArgumentList(superInit.arguments, types: true) + ..._emitArgumentList(superInit.arguments, types: true), ]; _currentTypeEnvironment = savedTypeEnvironment; @@ -2317,12 +2591,16 @@ return _emitSuperConstructorCall(ctor, className, ctor.name.text, args); } - js_ast.Statement _emitSuperConstructorCall(Constructor constructor, - js_ast.Expression className, String name, List<js_ast.Expression> args) { + js_ast.Statement _emitSuperConstructorCall( + Constructor constructor, + js_ast.Expression className, + String name, + List<js_ast.Expression> args, + ) { return js.statement('#.#.call(this, #);', [ _emitJSObjectGetPrototypeOf(className, fullyQualifiedName: true), _constructorName(name), - args + args, ]); } @@ -2353,11 +2631,15 @@ } js_ast.Expression _emitFieldInit( - Field f, Expression? initializer, TreeNode hoverInfo) { + Field f, + Expression? initializer, + TreeNode hoverInfo, + ) { var access = _emitFieldValueAccessor(f); var jsInit = _visitInitializer(initializer, f.annotations); return jsInit.toAssignExpression( - js.call('this.#', [access])..sourceInformation = _nodeStart(hoverInfo)); + js.call('this.#', [access])..sourceInformation = _nodeStart(hoverInfo), + ); } /// Initialize fields. They follow the sequence: @@ -2404,7 +2686,9 @@ } js_ast.Expression _visitInitializer( - Expression? init, List<Expression> annotations) { + Expression? init, + List<Expression> annotations, + ) { // explicitly initialize to null, to avoid getting `undefined`. // TODO(jmesserly): do this only for vars that aren't definitely assigned. if (init == null) return js_ast.LiteralNull(); @@ -2430,8 +2714,12 @@ mixin.constructors.every((c) => c.isExternal); } - js_ast.Statement _addConstructorToClass(Class c, js_ast.Expression className, - js_ast.LiteralString name, js_ast.Expression jsCtor) { + js_ast.Statement _addConstructorToClass( + Class c, + js_ast.Expression className, + js_ast.LiteralString name, + js_ast.Expression jsCtor, + ) { jsCtor = _defineValueOnClass(c, className, name, jsCtor); return js.statement('#.prototype = #.prototype;', [jsCtor, className]); } @@ -2458,9 +2746,10 @@ /// a static field. List<js_ast.Property> _emitStaticFieldAndAccessor(Member member) { return _emitLazyMember( - _emitTopLevelNameNoExternalInterop(member.enclosingClass!), - member, - (m) => _emitStaticMemberName(m.name.text)); + _emitTopLevelNameNoExternalInterop(member.enclosingClass!), + member, + (m) => _emitStaticMemberName(m.name.text), + ); } /// Emits class methods and properties. @@ -2474,14 +2763,22 @@ if (c == _coreTypes.objectClass) { // Dart does not use ES6 constructors. // Add an error to catch any invalid usage. - jsProperties.add(js_ast.Method( + jsProperties.add( + js_ast.Method( _propertyName('constructor'), - js.fun(r'''function() { + js.fun( + r'''function() { throw Error("use `new " + # + ".new(...)` to create a Dart object"); - }''', [ - _runtimeCall('typeName(#)', [_runtimeCall('getReifiedType(this)')]) - ]))); + }''', + [ + _runtimeCall('typeName(#)', [ + _runtimeCall('getReifiedType(this)'), + ]), + ], + ), + ), + ); } else if (c == _jsArrayClass) { // Provide access to the Array constructor property, so it works like // other native types (rather than calling the Dart Object "constructor" @@ -2489,8 +2786,12 @@ // // This will become obsolete when // https://github.com/dart-lang/sdk/issues/31003 is addressed. - jsProperties.add(js_ast.Method( - _propertyName('constructor'), js.fun(r'function() { return []; }'))); + jsProperties.add( + js_ast.Method( + _propertyName('constructor'), + js.fun(r'function() { return []; }'), + ), + ); } for (var m in c.fields) { @@ -2602,16 +2903,23 @@ fn = _emitNativeFunctionBody(member); } else { fn = _withMethodDeclarationContext( - member, - () => _emitFunction(member.function, member.name.text, - functionBody: _toSourceLocation(member.fileOffset), - functionEnd: _toSourceLocation(member.fileEndOffset))); + member, + () => _emitFunction( + member.function, + member.name.text, + functionBody: _toSourceLocation(member.fileOffset), + functionEnd: _toSourceLocation(member.fileEndOffset), + ), + ); } - var method = js_ast.Method(_declareMemberName(member), fn, - isGetter: member.isGetter, - isSetter: member.isSetter, - isStatic: member.isStatic); + var method = js_ast.Method( + _declareMemberName(member), + fn, + isGetter: member.isGetter, + isSetter: member.isSetter, + isStatic: member.isStatic, + ); if (isTearOffLowering(member)) { // Remove all source information from static methods introduced by the @@ -2635,7 +2943,9 @@ } else if (node.isSetter) { var params = _emitParameters(node.function); return js_ast.Fun( - params, js.block('{ this.# = #; }', [name, params.last])); + params, + js.block('{ this.# = #; }', [name, params.last]), + ); } else { var returnValue = js('this.#.apply(this, args)', [name]); if (_isNullCheckableNative(node)) { @@ -2671,26 +2981,37 @@ if (superMember is Field && isCovariantField(superMember) || superMember is Procedure && isCovariantParameter( - superMemberFunction!.positionalParameters[0])) { + superMemberFunction!.positionalParameters[0], + )) { return const []; } - var setterType = - substituteType(superMember.superSetterType).extensionTypeErasure; + var setterType = substituteType( + superMember.superSetterType, + ).extensionTypeErasure; if (_types.isTop(setterType)) return const []; return [ js_ast.Method( + name, + js.fun('function(x) { return super.# = #; }', [ name, - js.fun('function(x) { return super.# = #; }', - [name, _emitCast(_emitIdentifier('x'), setterType)]), - isSetter: true), - js_ast.Method(name, js.fun('function() { return super.#; }', [name]), - isGetter: true) + _emitCast(_emitIdentifier('x'), setterType), + ]), + isSetter: true, + ), + js_ast.Method( + name, + js.fun('function() { return super.#; }', [name]), + isGetter: true, + ), ]; } assert(!member.isAccessor); - var superMethodType = substituteType(superMemberFunction! - .computeThisFunctionType(Nullability.nonNullable)) as FunctionType; + var superMethodType = substituteType( + superMemberFunction!.computeThisFunctionType( + Nullability.nonNullable, + ), + ) as FunctionType; var function = member.function; var body = <js_ast.Statement>[]; @@ -2718,16 +3039,24 @@ var namedParameters = function.namedParameters; for (var param in namedParameters) { if (isCovariantParameter(param) && - !isCovariantParameter(superMemberFunction.namedParameters - .firstWhere((n) => n.name == param.name))) { + !isCovariantParameter( + superMemberFunction.namedParameters.firstWhere( + (n) => n.name == param.name, + ), + )) { var name = _propertyName(param.name!); - var paramType = superMethodType.namedParameters - .firstWhere((n) => n.name == param.name); - body.add(js.statement('if (#) #;', [ - _namedArgumentProbe(name), - _emitCast( - js_ast.PropertyAccess(_namedArgumentTemp, name), paramType.type) - ])); + var paramType = superMethodType.namedParameters.firstWhere( + (n) => n.name == param.name, + ); + body.add( + js.statement('if (#) #;', [ + _namedArgumentProbe(name), + _emitCast( + js_ast.PropertyAccess(_namedArgumentTemp, name), + paramType.type, + ), + ]), + ); } } @@ -2756,27 +3085,26 @@ final savedTypeEnvironment = _currentTypeEnvironment; _currentTypeEnvironment = RtiTypeEnvironment([ ...function.typeParameters, - ..._currentTypeEnvironment.classTypeParameters + ..._currentTypeEnvironment.classTypeParameters, ]); - var jsBody = js_ast.Block(_withCurrentFunction(function, () { - var block = _emitArgumentInitializers(function, name); - block.add(_emitFunctionScopedBody(function)); - return block; - })); + var jsBody = js_ast.Block( + _withCurrentFunction(function, () { + var block = _emitArgumentInitializers(function, name); + block.add(_emitFunctionScopedBody(function)); + return block; + }), + ); var jsName = _constructorName(name); memberNames[node] = jsName.valueWithoutQuotes; // Generic class constructors accept their RTI as their first argument. var method = js_ast.Method( jsName, - js_ast.Fun( - [ - if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam, - ..._emitParameters(function) - ], - jsBody, - ), + js_ast.Fun([ + if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam, + ..._emitParameters(function), + ], jsBody), isStatic: true, )..sourceInformation = _nodeEnd(node.fileEndOffset); _currentTypeEnvironment = savedTypeEnvironment; @@ -2815,12 +3143,17 @@ : [ js_ast.This(), virtualFieldSymbol, - if (isCovariantField(field)) _emitCast(value, field.type) else value + if (isCovariantField(field)) + _emitCast(value, field.type) + else + value, ]; body.add(js.call('#[#] = #', args).toStatement()); - var jsSetter = js_ast.Method(name, js_ast.Fun([value], js_ast.Block(body)), - isSetter: true) - ..sourceInformation = _nodeStart(field); + var jsSetter = js_ast.Method( + name, + js_ast.Fun([value], js_ast.Block(body)), + isSetter: true, + )..sourceInformation = _nodeStart(field); return [jsGetter, jsSetter]; } @@ -2860,8 +3193,11 @@ /// This is needed because in ES6, if you only override a getter /// (alternatively, a setter), then there is an implicit override of the /// setter (alternatively, the getter) that does nothing. - js_ast.Method? _emitSuperAccessorWrapper(Procedure member, - Map<String, Procedure> getters, Map<String, Procedure> setters) { + js_ast.Method? _emitSuperAccessorWrapper( + Procedure member, + Map<String, Procedure> getters, + Map<String, Procedure> setters, + ) { if (member.isAbstract) return null; var name = member.name.text; @@ -2903,8 +3239,10 @@ var parent = _hierarchy.getDispatchTarget(superclass, Name('iterator')); if (parent != null) return null; - var parentIterable = - _hierarchy.getClassAsInstanceOf(superclass, _coreTypes.iterableClass); + var parentIterable = _hierarchy.getClassAsInstanceOf( + superclass, + _coreTypes.iterableClass, + ); if (parentIterable != null) return null; if (c.enclosingLibrary.importUri.isScheme('dart') && @@ -2915,25 +3253,34 @@ // Otherwise, emit the adapter method, which wraps the Dart iterator in // an ES6 iterator. return js_ast.Method( - js.call('Symbol.iterator'), - // TODO(nshahan) Don't access values in `runtimeModule` outside of - // `runtimeCall`. - js.call('function() { return new #.JsIterator(this.#); }', [ - _emitLibraryName(_runtimeLibrary), - _emitMemberName('iterator', memberClass: _coreTypes.iterableClass) - ]) as js_ast.Fun); + js.call('Symbol.iterator'), + // TODO(nshahan) Don't access values in `runtimeModule` outside of + // `runtimeCall`. + js.call('function() { return new #.JsIterator(this.#); }', [ + _emitLibraryName(_runtimeLibrary), + _emitMemberName('iterator', memberClass: _coreTypes.iterableClass), + ]) as js_ast.Fun, + ); } void _registerExtensionType( - Class c, String jsPeerName, List<js_ast.Statement> body) { + Class c, + String jsPeerName, + List<js_ast.Statement> body, + ) { var className = _emitTopLevelName(c); // TODO(55547): Move these operations to the library link method. if (_typeRep.isPrimitive(_coreTypes.nonNullableRawType(c))) { - body.add(_runtimeStatement( - 'definePrimitiveHashCode(#.prototype)', [className])); + body.add( + _runtimeStatement('definePrimitiveHashCode(#.prototype)', [className]), + ); } - _nativeExtensionLinks.add(_runtimeStatement( - 'registerExtension(#, #)', [js.string(jsPeerName), className])); + _nativeExtensionLinks.add( + _runtimeStatement('registerExtension(#, #)', [ + js.string(jsPeerName), + className, + ]), + ); } /// Generates an entrypoint function for [field] that returns the value in @@ -2941,8 +3288,11 @@ /// /// [valueCache] is 'undefined' when uninitialized and holds a special /// sentinel value if [field] is final to detect multiple initializations. - js_ast.Fun _emitLazyInitializingFunction(js_ast.Expression valueCache, - js_ast.Expression initializer, Field field) { + js_ast.Fun _emitLazyInitializingFunction( + js_ast.Expression valueCache, + js_ast.Expression initializer, + Field field, + ) { var initialFieldValueExpression = !_compileForHotReload ? valueCache : _emitCast(valueCache, field.type); // Lazy static fields require an additional type check around their value @@ -2958,7 +3308,8 @@ // initialization cycles via a special sentinel. if (field.isFinal) { var finalLateInitDetectorSentinel = _getSymbol( - _emitPrivateNameSymbol(field.enclosingLibrary, '_#initializing')); + _emitPrivateNameSymbol(field.enclosingLibrary, '_#initializing'), + ); // Emits code like: // // if ([valueCache] === _#initializing) @@ -2982,7 +3333,8 @@ // } // }); // return this.field; - return js.fun(r''' + return js.fun( + r''' function() { if (# === #) #; if (# === void 0) { @@ -3004,26 +3356,27 @@ }); return this.#; } - ''', [ - valueCache, - finalLateInitDetectorSentinel, - _runtimeCall( - 'throwLateInitializationError(#)', - [js.string(field.name.text)], - ), - valueCache, - valueCache, - finalLateInitDetectorSentinel, - valueCache, - initializer, - valueCache, - finalLateInitDetectorSentinel, - valueCache, - initialFieldValueExpression, - js.string(getterName), - valueCache, - getterName, - ]); + ''', + [ + valueCache, + finalLateInitDetectorSentinel, + _runtimeCall('throwLateInitializationError(#)', [ + js.string(field.name.text), + ]), + valueCache, + valueCache, + finalLateInitDetectorSentinel, + valueCache, + initializer, + valueCache, + finalLateInitDetectorSentinel, + valueCache, + initialFieldValueExpression, + js.string(getterName), + valueCache, + getterName, + ], + ); } else { // Emits code like: // @@ -3037,7 +3390,8 @@ // } // }); // return this.field; - return js.fun(r''' + return js.fun( + r''' function() { if (# === void 0) { # = #; @@ -3050,22 +3404,25 @@ }); return this.#; } - ''', [ - valueCache, - valueCache, - initializer, - initialFieldValueExpression, - js.string(getterName), - valueCache, - getterName, - ]); + ''', + [ + valueCache, + valueCache, + initializer, + initialFieldValueExpression, + js.string(getterName), + valueCache, + getterName, + ], + ); } } // Final fields are generated with additional logic to detect // initialization cycles via a special sentinel. if (field.isFinal) { var finalLateInitDetectorSentinel = _getSymbol( - _emitPrivateNameSymbol(field.enclosingLibrary, '_#initializing')); + _emitPrivateNameSymbol(field.enclosingLibrary, '_#initializing'), + ); // Emits code like: // // if ([valueCache] === _#initializing) @@ -3083,7 +3440,8 @@ // } // } // return [valueCache]; - return js.fun(r''' + return js.fun( + r''' function() { if (# === #) #; if (# === void 0) { @@ -3099,37 +3457,36 @@ } return #; } - ''', [ - valueCache, - finalLateInitDetectorSentinel, - _runtimeCall( - 'throwLateInitializationError(#)', - [js.string(field.name.text)], - ), - valueCache, - valueCache, - finalLateInitDetectorSentinel, - valueCache, - initializer, - valueCache, - finalLateInitDetectorSentinel, - valueCache, - initialFieldValueExpression, - ]); + ''', + [ + valueCache, + finalLateInitDetectorSentinel, + _runtimeCall('throwLateInitializationError(#)', [ + js.string(field.name.text), + ]), + valueCache, + valueCache, + finalLateInitDetectorSentinel, + valueCache, + initializer, + valueCache, + finalLateInitDetectorSentinel, + valueCache, + initialFieldValueExpression, + ], + ); } else { - return js.fun(r''' + return js.fun( + r''' function() { if (# === void 0) { # = #; } return #; } - ''', [ - valueCache, - valueCache, - initializer, - initialFieldValueExpression, - ]); + ''', + [valueCache, valueCache, initializer, initialFieldValueExpression], + ); } } @@ -3138,8 +3495,11 @@ /// Lazy fields are represented as an inlined initializer and a value store. /// Value stores are JS symbols prefixed by [_fieldValueStorePrefix], are /// initialized on first access, and are not replaced after a hot reload. - List<js_ast.Property> _emitLazyMember(js_ast.Expression objExpr, - Member member, js_ast.LiteralString Function(Member) emitMemberName) { + List<js_ast.Property> _emitLazyMember( + js_ast.Expression objExpr, + Member member, + js_ast.LiteralString Function(Member) emitMemberName, + ) { _currentUri = member.fileUri; _staticTypeContext.enterMember(member); var access = emitMemberName(member); @@ -3156,63 +3516,80 @@ ? memberNames[member]! : '$_fieldValueStorePrefix${memberNames[member]!}'; var memberValueStore = _getSymbol( - _emitPrivateNameSymbol(_currentLibrary!, fieldValueStoreName)); - properties.add(js_ast.Property(memberValueStore, js.call('void 0'), + _emitPrivateNameSymbol(_currentLibrary!, fieldValueStoreName), + ); + properties.add( + js_ast.Property( + memberValueStore, + js.call('void 0'), isStatic: member.isStatic && member.enclosingClass != null, - isClassProperty: member.enclosingClass != null)); + isClassProperty: member.enclosingClass != null, + ), + ); - var initializer = - _visitInitializer(member.initializer, member.annotations); + var initializer = _visitInitializer( + member.initializer, + member.annotations, + ); js_ast.Fun getter; if (_isNonHotReloadableResource(_currentLibrary!.importUri)) { getter = js.fun( - 'function() { return this[#] === void 0 ? this[#] = # : this[#]; }', - [ - memberValueStore, - memberValueStore, - initializer, - memberValueStore - ]); + 'function() { return this[#] === void 0 ? this[#] = # : this[#]; }', + [memberValueStore, memberValueStore, initializer, memberValueStore], + ); } else { getter = _emitLazyInitializingFunction( - js.call('this.#', memberValueStore), initializer, member); + js.call('this.#', memberValueStore), + initializer, + member, + ); } - properties.add(js_ast.Method(access, getter, + properties.add( + js_ast.Method( + access, + getter, isGetter: true, - isStatic: member.isStatic && member.enclosingClass != null) - ..sourceInformation = _hoverComment( - js_ast.PropertyAccess(objExpr, access), - member.fileOffset, - member.name.text.length, - )); + isStatic: member.isStatic && member.enclosingClass != null, + )..sourceInformation = _hoverComment( + js_ast.PropertyAccess(objExpr, access), + member.fileOffset, + member.name.text.length, + ), + ); if (!member.isFinal && !member.isConst) { var body = <js_ast.Statement>[]; var param = _emitIdentifier('v'); body.add(js.statement('this.# = #;', [memberValueStore, param])); // Even when no null check is present a dummy setter is still required // to indicate writeable. - properties.add(js_ast.Method( - access, - js_ast.Fun([param], js_ast.Block(body)), - isSetter: true, - isStatic: member.isStatic && member.enclosingClass != null, - )); + properties.add( + js_ast.Method( + access, + js_ast.Fun([param], js_ast.Block(body)), + isSetter: true, + isStatic: member.isStatic && member.enclosingClass != null, + ), + ); } } else if (member is Procedure) { - properties.add(js_ast.Method( - access, - _emitFunction(member.function, member.name.text), - isGetter: member.isGetter, - isSetter: member.isSetter, - isStatic: member.isStatic && member.enclosingClass != null, - )..sourceInformation = _hoverComment( - js_ast.PropertyAccess(objExpr, access), - member.fileOffset, - member.name.text.length)); + properties.add( + js_ast.Method( + access, + _emitFunction(member.function, member.name.text), + isGetter: member.isGetter, + isSetter: member.isSetter, + isStatic: member.isStatic && member.enclosingClass != null, + )..sourceInformation = _hoverComment( + js_ast.PropertyAccess(objExpr, access), + member.fileOffset, + member.name.text.length, + ), + ); } else { throw UnsupportedError( - 'Unsupported lazy member type ${member.runtimeType}: $member'); + 'Unsupported lazy member type ${member.runtimeType}: $member', + ); } _staticTypeContext.leaveMember(member); return properties; @@ -3235,7 +3612,8 @@ } List<js_ast.Statement> _withLetScope( - List<js_ast.Statement> Function() visitBody) { + List<js_ast.Statement> Function() visitBody, + ) { var savedLetVariables = _letVariables; _letVariables = []; @@ -3261,10 +3639,12 @@ var name = m.name.text; var actualUseExtension = useExtension || (c != null && _extensionTypes.isNativeClass(c)); - return _emitMemberName(name, - isStatic: m is Field ? m.isStatic : (m as Procedure).isStatic, - useExtension: actualUseExtension, - member: m); + return _emitMemberName( + name, + isStatic: m is Field ? m.isStatic : (m as Procedure).isStatic, + useExtension: actualUseExtension, + member: m, + ); } /// This handles member renaming for private names and operators. @@ -3307,11 +3687,13 @@ /// Equality is a bit special, it is generated via the Dart `equals` runtime /// helper, that checks for null. The user defined method is called '=='. /// - js_ast.Expression _emitMemberName(String name, - {bool isStatic = false, - bool? useExtension, - Member? member, - Class? memberClass}) { + js_ast.Expression _emitMemberName( + String name, { + bool isStatic = false, + bool? useExtension, + Member? member, + Class? memberClass, + }) { // Static members skip the rename steps and may require JS interop renames. if (isStatic) { var memberName = _emitStaticMemberName(name, member); @@ -3350,8 +3732,8 @@ _currentLibrary!; if (member != null) { // TODO(40273) Move this name collection to another location. - // We really only want to collect member names when the member is created, - // not called. + // We really only want to collect member names when the member is + // created, not called. // Wrap the name as a symbol here so it matches what you would find at // runtime when you get all properties and symbols from an instance. memberNames[member] = 'Symbol($name)'; @@ -3420,10 +3802,11 @@ var map = _forwardingCache.putIfAbsent(c, () => {}); return map.putIfAbsent( - name, - () => - _hierarchy.getDispatchTarget(c, Name(name)) ?? - _hierarchy.getDispatchTarget(c, Name(name), setter: true)); + name, + () => + _hierarchy.getDispatchTarget(c, Name(name)) ?? + _hierarchy.getDispatchTarget(c, Name(name), setter: true), + ); } js_ast.LiteralString _emitStaticMemberName(String name, [NamedNode? member]) { @@ -3476,7 +3859,9 @@ (type is InterfaceType && type.classNode == _coreTypes.functionClass)) { if (!isAllowInterop(f)) { return StaticInvocation( - _assertInteropMethod, Arguments([f], types: [type])); + _assertInteropMethod, + Arguments([f], types: [type]), + ); } } return f; @@ -3487,24 +3872,30 @@ if (!usesJSInterop(n)) return null; if (n is Member && !n.isExternal) return null; var name = _annotationName(n, isJSInteropAnnotation) ?? getTopLevelName(n); - assert(!name.contains('.'), - 'JS interop checker rejects dotted names on static class members'); + assert( + !name.contains('.'), + 'JS interop checker rejects dotted names on static class members', + ); return js.escapedString(name, "'"); } /// Emit the top-level name associated with [n], which should not be an /// external interop member. - js_ast.PropertyAccess _emitTopLevelNameNoExternalInterop(NamedNode n, - {String suffix = '', bool resolvedFromEmbedder = false}) { + js_ast.PropertyAccess _emitTopLevelNameNoExternalInterop( + NamedNode n, { + String suffix = '', + bool resolvedFromEmbedder = false, + }) { // Some native tests use top-level native methods. var isTopLevelNative = n is Member && isNative(n); return js_ast.PropertyAccess( - isTopLevelNative - ? _runtimeCall('global.self') - : (resolvedFromEmbedder - ? _emitEmbedderResolvedLibrary(getLibrary(n)) - : _emitLibraryName(getLibrary(n))), - _emitTopLevelMemberName(n, suffix: suffix)); + isTopLevelNative + ? _runtimeCall('global.self') + : (resolvedFromEmbedder + ? _emitEmbedderResolvedLibrary(getLibrary(n)) + : _emitLibraryName(getLibrary(n))), + _emitTopLevelMemberName(n, suffix: suffix), + ); } /// Emits [library] fully resolved via the Dart Dev Embedder. @@ -3520,8 +3911,10 @@ /// /// NOTE: usually you should use [_emitTopLevelName] instead of this. This /// function does not handle JS interop. - js_ast.LiteralString _emitTopLevelMemberName(NamedNode n, - {String suffix = ''}) { + js_ast.LiteralString _emitTopLevelMemberName( + NamedNode n, { + String suffix = '', + }) { var name = _jsExportName(n) ?? getTopLevelName(n); return _propertyName(name + suffix); } @@ -3592,7 +3985,9 @@ js_ast.PropertyAccess? access; for (var part in parts) { access = js_ast.PropertyAccess( - access ?? _runtimeCall('global'), js.escapedString(part, "'")); + access ?? _runtimeCall('global'), + js.escapedString(part, "'"), + ); } return access!; } @@ -3608,8 +4003,9 @@ // Emit procedures var procedures = library.procedures - .where((p) => - !p.isExternal && !p.isAbstract && !_isStaticInteropTearOff(p)) + .where( + (p) => !p.isExternal && !p.isAbstract && !_isStaticInteropTearOff(p), + ) .toList(); for (var p in procedures) { if (!p.isAccessor) { @@ -3620,10 +4016,13 @@ // can tag them during the delta diff phase. if (p.isStatic && _reifyTearoff(p) && !p.isExternal) { var nameExpr = _emitTopLevelName(p); - _moduleItems.add(_emitFunctionTagged(nameExpr, - p.function.computeThisFunctionType(Nullability.nonNullable), - asLazy: true) - .toStatement()); + _moduleItems.add( + _emitFunctionTagged( + nameExpr, + p.function.computeThisFunctionType(Nullability.nonNullable), + asLazy: true, + ).toStatement(), + ); } } if (_hotReloadLibraryMetadata != null) { @@ -3634,8 +4033,11 @@ // The name used here must match the name used when creating top level // members. See [getTopLevelName]. var methodName = _propertyName(deletedProcedureName); - _moduleItems.add(js.statement('delete #', - [js_ast.PropertyAccess(_emitLibraryName(library), methodName)])); + _moduleItems.add( + js.statement('delete #', [ + js_ast.PropertyAccess(_emitLibraryName(library), methodName), + ]), + ); } } var accessors = @@ -3666,10 +4068,12 @@ init is ConstructorInvocation && isInternalConstructor(init) || init is StaticInvocation && isInlineJS(init.target)) { _currentUri = field.fileUri; - _moduleItems.add(js.statement('# = #;', [ - _emitTopLevelName(field), - _visitInitializer(init, field.annotations) - ])); + _moduleItems.add( + js.statement('# = #;', [ + _emitTopLevelName(field), + _visitInitializer(init, field.annotations), + ]), + ); } else { lazyFields.add(field); } @@ -3683,13 +4087,18 @@ var libraryExpr = _emitLibraryName(_currentLibrary!); if (fields.isNotEmpty) { libraryProperties.addAll( - _emitLazyMembers(libraryExpr, fields, _emitTopLevelMemberName)); + _emitLazyMembers(libraryExpr, fields, _emitTopLevelMemberName), + ); } if (libraryProperties.isNotEmpty) { var propertiesObject = js_ast.ObjectInitializer(libraryProperties); - _moduleItems.add(_runtimeStatement( - 'declareTopLevelProperties(#, #)', [libraryExpr, propertiesObject])); + _moduleItems.add( + _runtimeStatement('declareTopLevelProperties(#, #)', [ + libraryExpr, + propertiesObject, + ]), + ); } } @@ -3717,14 +4126,18 @@ final factoryName = extractConstructorNameFromTearOff(p.name); if (factoryName != null) { if (factoryName.isEmpty && - enclosingClass.constructors.any((constructor) => - constructor.isSynthetic && constructor.name.text.isEmpty)) { + enclosingClass.constructors.any( + (constructor) => + constructor.isSynthetic && constructor.name.text.isEmpty, + )) { return true; } - if (enclosingClass.procedures.any((procedure) => - procedure.isFactory && - procedure.isExternal && - procedure.name.text == factoryName)) { + if (enclosingClass.procedures.any( + (procedure) => + procedure.isFactory && + procedure.isExternal && + procedure.name.text == factoryName, + )) { return true; } } @@ -3740,9 +4153,11 @@ var name = node.name.text; memberNames[node] = name; var result = js_ast.Method( - _propertyName(name), _emitFunction(node.function, name), - isGetter: node.isGetter, isSetter: node.isSetter) - ..sourceInformation = _nodeEnd(node.fileEndOffset); + _propertyName(name), + _emitFunction(node.function, name), + isGetter: node.isGetter, + isSetter: node.isSetter, + )..sourceInformation = _nodeEnd(node.fileEndOffset); _currentUri = savedUri; _staticTypeContext.leaveMember(node); @@ -3755,10 +4170,12 @@ _currentUri = p.fileUri; var body = <js_ast.Statement>[]; - var fn = _emitFunction(p.function, p.name.text, - functionBody: _toSourceLocation(p.fileOffset), - functionEnd: _toSourceLocation(p.fileEndOffset)) - ..sourceInformation = _nodeEnd(p.fileEndOffset); + var fn = _emitFunction( + p.function, + p.name.text, + functionBody: _toSourceLocation(p.fileOffset), + functionEnd: _toSourceLocation(p.fileEndOffset), + )..sourceInformation = _nodeEnd(p.fileEndOffset); if (_currentLibrary!.importUri.isScheme('dart') && _isInlineJSFunction(p.function.body)) { @@ -3769,8 +4186,9 @@ var jsName = _safeFunctionNameForSafari(p.name.text, fn); var functionName = _emitScopedId(jsName); procedureIdentifiers[p] = functionName; - body.add(js.statement( - '# = #', [nameExpr, js_ast.NamedFunction(functionName, fn)])); + body.add( + js.statement('# = #', [nameExpr, js_ast.NamedFunction(functionName, fn)]), + ); _currentUri = savedUri; _staticTypeContext.leaveMember(p); @@ -3781,8 +4199,10 @@ if (p.function.requiredParameterCount > 0) { // TODO(sigmund): this error should be caught by a kernel checker that // runs prior to DDC. - throw StateError('Entrypoint ${p.name.text} must accept being called ' - 'with 0 arguments.'); + throw StateError( + 'Entrypoint ${p.name.text} must accept being called ' + 'with 0 arguments.', + ); } else { _dynamicEntrypoint = p; } @@ -3809,7 +4229,9 @@ /// name overlap with the parameter names as well. This rename works around /// such bug (dartbug.com/43520). static String _safeFunctionNameForSafari( - String candidateName, js_ast.Fun fn) { + String candidateName, + js_ast.Fun fn, + ) { if (fn.params.any((p) => p is js_ast.DestructuredVariable)) { while (fn.params.any((a) => a.parameterName == candidateName)) { candidateName = '$candidateName\$'; @@ -3818,8 +4240,11 @@ return candidateName; } - js_ast.Expression _emitFunctionTagged(js_ast.Expression fn, FunctionType type, - {bool asLazy = false}) { + js_ast.Expression _emitFunctionTagged( + js_ast.Expression fn, + FunctionType type, { + bool asLazy = false, + }) { assert(type.nullability == Nullability.nonNullable); var typeRep = _emitType(type); if (type.typeParameters.isEmpty) { @@ -3829,15 +4254,23 @@ } else { var typeParameterDefaults = [ for (var parameter in type.typeParameters) - _emitType(parameter.defaultType) + _emitType(parameter.defaultType), ]; - var defaultInstantiatedBounds = - _emitConstList(const DynamicType(), typeParameterDefaults); + var defaultInstantiatedBounds = _emitConstList( + const DynamicType(), + typeParameterDefaults, + ); return asLazy - ? _runtimeCall('lazyGFn(#, () => #, () => #)', - [fn, typeRep, defaultInstantiatedBounds]) - : _runtimeCall( - 'gFn(#, #, #)', [fn, typeRep, defaultInstantiatedBounds]); + ? _runtimeCall('lazyGFn(#, () => #, () => #)', [ + fn, + typeRep, + defaultInstantiatedBounds, + ]) + : _runtimeCall('gFn(#, #, #)', [ + fn, + typeRep, + defaultInstantiatedBounds, + ]); } } @@ -3850,16 +4283,22 @@ /// in most cases except for uses in non-external JS interop factories. /// Note: This only applies to the old style package:js interop and isn't /// necessary for any forms of static JS interop. - js_ast.Expression _emitType(DartType type, - {bool emitJSInteropGenericClassTypeParametersAsAny = true}) { + js_ast.Expression _emitType( + DartType type, { + bool emitJSInteropGenericClassTypeParametersAsAny = true, + }) { /// Returns an expression that evaluates a type [recipe] within the type /// [environment]. /// /// At runtime the expression will evaluate to an rti object. js_ast.Expression emitRtiEval( - js_ast.Expression environment, String recipe) => - js.call('#.#("$recipe")', - [environment, _emitMemberName('_eval', memberClass: _rtiClass)]); + js_ast.Expression environment, + String recipe, + ) => + js.call('#.#("$recipe")', [ + environment, + _emitMemberName('_eval', memberClass: _rtiClass), + ]); /// Returns an expression that binds a type [parameter] within the type /// [environment]. @@ -3867,29 +4306,34 @@ /// At runtime the expression will evaluate to an rti object that has been /// extended to include the provided [parameter]. js_ast.Expression emitRtiBind( - js_ast.Expression environment, TypeParameter parameter) { + js_ast.Expression environment, + TypeParameter parameter, + ) { return js.call('#.#(#)', [ environment, _emitMemberName('_bind', memberClass: _rtiClass), - _emitTypeParameter(parameter) + _emitTypeParameter(parameter), ]); } /// Returns an expression that evaluates a type [recipe] in a type /// [environment] resulting in an rti object. js_ast.Expression evalInEnvironment( - DDCTypeEnvironment environment, String recipe) { + DDCTypeEnvironment environment, + String recipe, + ) { switch (environment) { case EmptyTypeEnvironment(): - // Cache ground types in the type table for fast lookup. The table will - // lazily lookup the RTI object on first access and then replace the - // lazy getter with the initialized RTI object. + // Cache ground types in the type table for fast lookup. The table + // will lazily lookup the RTI object on first access and then replace + // the lazy getter with the initialized RTI object. return _typeTable.nameType( - type, - js.call('#._Universe.eval(#, "$recipe", true)', [ - _emitLibraryName(_rtiLibrary), - _runtimeCall('typeUniverse'), - ])); + type, + js.call('#._Universe.eval(#, "$recipe", true)', [ + _emitLibraryName(_rtiLibrary), + _runtimeCall('typeUniverse'), + ]), + ); case BindingTypeEnvironment(): js_ast.Expression env; if (environment.isSingleTypeParameter) { @@ -3901,8 +4345,10 @@ } else { var environmentTypes = environment.functionTypeParameters; // Create a dummy interface type to "hold" type arguments. - env = - emitRtiEval(_emitTypeParameter(environmentTypes.first), '@<0>'); + env = emitRtiEval( + _emitTypeParameter(environmentTypes.first), + '@<0>', + ); // Bind remaining type arguments. for (var i = 1; i < environmentTypes.length; i++) { env = emitRtiBind(env, environmentTypes[i]); @@ -3917,34 +4363,43 @@ case ClassTypeEnvironment(): // Class type environments are already constructed and attached to the // instance of a generic class. - var env = - js.call('#.instanceType(this)', [_emitLibraryName(_rtiLibrary)]); + var env = js.call('#.instanceType(this)', [ + _emitLibraryName(_rtiLibrary), + ]); return emitRtiEval(env, recipe); case ExtendedTypeEnvironment(): // Class type environments are already constructed and attached to the // instance of a generic class, but function type parameters need to // be bound. - var env = - js.call('#.instanceType(this)', [_emitLibraryName(_rtiLibrary)]); + var env = js.call('#.instanceType(this)', [ + _emitLibraryName(_rtiLibrary), + ]); // Bind extra type parameters. for (var parameter in environment.functionTypeParameters) { env = emitRtiBind(env, parameter); } return emitRtiEval(env, recipe); } - _typeCompilationError(type, - 'Unexpected DDCTypeEnvironment type (${environment.runtimeType}).'); + _typeCompilationError( + type, + 'Unexpected DDCTypeEnvironment type (${environment.runtimeType}).', + ); } - var normalizedType = - _futureOrNormalizer.normalize(type.extensionTypeErasure); + var normalizedType = _futureOrNormalizer.normalize( + type.extensionTypeErasure, + ); try { var result = _typeRecipeGenerator.recipeInEnvironment( - normalizedType, _currentTypeEnvironment, - emitJSInteropGenericClassTypeParametersAsAny: - emitJSInteropGenericClassTypeParametersAsAny); - var typeRep = - evalInEnvironment(result.requiredEnvironment, result.recipe); + normalizedType, + _currentTypeEnvironment, + emitJSInteropGenericClassTypeParametersAsAny: + emitJSInteropGenericClassTypeParametersAsAny, + ); + var typeRep = evalInEnvironment( + result.requiredEnvironment, + result.recipe, + ); return typeRep; } on UnsupportedError catch (e) { _typeCompilationError(normalizedType, e.message ?? 'Unknown Error'); @@ -3953,8 +4408,9 @@ js_ast.Expression _emitInvalidNode(Node node, [String message = '']) { if (message.isNotEmpty) message += ' '; - return _runtimeCall('throwUnimplementedError(#)', - [js.escapedString('node <${node.runtimeType}> $message`$node`')]); + return _runtimeCall('throwUnimplementedError(#)', [ + js.escapedString('node <${node.runtimeType}> $message`$node`'), + ]); } /// Emits a reference to the class described by [type]. @@ -3972,14 +4428,20 @@ /// [resolvedFromEmbedder] looks up [type] via the embedder, which retrieves /// the correct library in the context of hot reload. This should not be set /// for external classes. - js_ast.Expression _emitClassRef(InterfaceType type, - {bool resolvedFromEmbedder = false}) => - _emitTopLevelNameNoExternalInterop(type.classNode, - resolvedFromEmbedder: resolvedFromEmbedder); + js_ast.Expression _emitClassRef( + InterfaceType type, { + bool resolvedFromEmbedder = false, + }) => + _emitTopLevelNameNoExternalInterop( + type.classNode, + resolvedFromEmbedder: resolvedFromEmbedder, + ); Never _typeCompilationError(DartType type, String description) => - throw UnsupportedError('$description Encountered while compiling ' - '${_currentLibrary!.fileUri}, which contains the type: $type.'); + throw UnsupportedError( + '$description Encountered while compiling ' + '${_currentLibrary!.fileUri}, which contains the type: $type.', + ); /// Emits an expression that lets you access statics on a [type] from code. js_ast.Expression _emitConstructorName(InterfaceType type, Member c) { @@ -3994,7 +4456,9 @@ // If it's non-external but belongs to an interop class, we want the class // reference we defined in `_emitJSInteropClassNonExternalMembers`. return js_ast.PropertyAccess( - _emitClassRef(type), _constructorName(c.name.text)); + _emitClassRef(type), + _constructorName(c.name.text), + ); } /// Emits an expression that lets you access statics on [c] from code. @@ -4007,7 +4471,8 @@ } js_ast.Identifier _emitTypeParameter( - /* TypeParameter | StructuralParameter */ Object t) { + /* TypeParameter | StructuralParameter */ Object t, + ) { assert(t is TypeParameter || t is StructuralParameter); return _emitIdentifier(getTypeParameterName(t)); } @@ -4025,7 +4490,8 @@ void _setIncrementalMode() { if (!_moduleEmitted) { throw StateError( - 'Cannot run in incremental mode before module completion'); + 'Cannot run in incremental mode before module completion', + ); } _incrementalModules.clear(); _privateNames.clear(); @@ -4050,8 +4516,13 @@ /// by the debugger. /// Triggers incremental mode, which only emits symbols, types, constants, /// libraries, and uris referenced in the expression compilation result. - js_ast.Fun _emitFunctionIncremental(List<ModuleItem> items, Library library, - Class? cls, FunctionNode functionNode, String name) { + js_ast.Fun _emitFunctionIncremental( + List<ModuleItem> items, + Library library, + Class? cls, + FunctionNode functionNode, + String name, + ) { // Setup context. _currentLibrary = library; _staticTypeContext.enterLibrary(_currentLibrary!); @@ -4088,7 +4559,7 @@ ..._symbolContainer.emit(), ..._emitConstTable(), ..._uriContainer.emit(), - ...fun.body.statements + ...fun.body.statements, ]); // Import all necessary libraries, including libraries accessed from the @@ -4105,23 +4576,33 @@ List<js_ast.Statement> _emitConstTable() { var constTable = <js_ast.Statement>[]; if (_constLazyAccessors.isNotEmpty) { - constTable - .add(js.statement('const # = Object.create(null);', [_constTable])); + constTable.add( + js.statement('const # = Object.create(null);', [_constTable]), + ); - constTable.add(_runtimeStatement( - 'defineLazy(#, { # })', [_constTable, _constLazyAccessors])); + constTable.add( + _runtimeStatement('defineLazy(#, { # })', [ + _constTable, + _constLazyAccessors, + ]), + ); constTable.addAll(_constTableCache.emit()); } return constTable; } - js_ast.Fun _emitFunction(FunctionNode f, String? name, - {SourceLocation? functionEnd, SourceLocation? functionBody}) { + js_ast.Fun _emitFunction( + FunctionNode f, + String? name, { + SourceLocation? functionEnd, + SourceLocation? functionBody, + }) { var savedTypeEnvironment = _currentTypeEnvironment; if (f.typeParameters.isNotEmpty) { - _currentTypeEnvironment = - _currentTypeEnvironment.extend(f.typeParameters); + _currentTypeEnvironment = _currentTypeEnvironment.extend( + f.typeParameters, + ); } var formals = _emitParameters(f); var typeFormals = _emitTypeFormals(f.typeParameters); @@ -4135,22 +4616,30 @@ // potentially mutated in Kernel. For now we assume all parameters are. _enterFunction(name, formals, () => true); - var block = js_ast.Block(_withCurrentFunction(f, () { - final bodyPrefix = _emitArgumentInitializers(f, name); + var block = js_ast.Block( + _withCurrentFunction(f, () { + final bodyPrefix = _emitArgumentInitializers(f, name); - // Do the async transformation before adding parameter initialization - // logic. Any parameter initialization should be performed synchronously - // before the async body is evaluated. - final bodyFn = - js_ast.Fun(formals, js_ast.Block([_emitFunctionScopedBody(f)])); - final rewrittenFunction = _rewriteAsyncFunction( - bodyFn, f.asyncMarker, name, f.emittedValueType, + // Do the async transformation before adding parameter initialization + // logic. Any parameter initialization should be performed synchronously + // before the async body is evaluated. + final bodyFn = js_ast.Fun( + formals, + js_ast.Block([_emitFunctionScopedBody(f)]), + ); + final rewrittenFunction = _rewriteAsyncFunction( + bodyFn, + f.asyncMarker, + name, + f.emittedValueType, functionEnd: functionEnd, functionBody: functionBody, - bodyPrefix: bodyPrefix); - formals = rewrittenFunction.params; - return rewrittenFunction.body.statements; - })); + bodyPrefix: bodyPrefix, + ); + formals = rewrittenFunction.params; + return rewrittenFunction.body.statements; + }), + ); block = _exitFunction(formals, block); var fn = js_ast.Fun(formals, block); @@ -4165,11 +4654,15 @@ /// [bodyPrefix] will get prepended to the body of the rewritten function and /// any references to parameters within it will be replaced with the correct /// temporary ID for that parameter. - js_ast.Fun _rewriteAsyncFunction(js_ast.Fun fun, AsyncMarker asyncMarker, - String? name, DartType? asyncType, - {SourceLocation? functionEnd, - SourceLocation? functionBody, - List<js_ast.Statement>? bodyPrefix}) { + js_ast.Fun _rewriteAsyncFunction( + js_ast.Fun fun, + AsyncMarker asyncMarker, + String? name, + DartType? asyncType, { + SourceLocation? functionEnd, + SourceLocation? functionBody, + List<js_ast.Statement>? bodyPrefix, + }) { AsyncRewriterBase? asyncRewriter; final bodyName = _emitScopedId('t\$async${name ?? 'Body'}'); switch (asyncMarker) { @@ -4177,68 +4670,93 @@ break; case AsyncMarker.Async: asyncRewriter = AsyncRewriter( - asyncStart: _emitTopLevelNameNoExternalInterop(_asyncStartMember), - asyncAwait: _emitTopLevelNameNoExternalInterop(_asyncAwaitMember), - asyncReturn: _emitTopLevelNameNoExternalInterop(_asyncReturnMember), - asyncRethrow: - _emitTopLevelNameNoExternalInterop(_asyncRethrowMember), - completerFactory: - _emitTopLevelNameNoExternalInterop(_asyncMakeCompleterMember), - completerFactoryTypeArguments: [ - _emitType(asyncType!), - ], - wrapBody: - _emitTopLevelNameNoExternalInterop(_asyncWrapJsFunctionMember), - bodyName: bodyName); + asyncStart: _emitTopLevelNameNoExternalInterop(_asyncStartMember), + asyncAwait: _emitTopLevelNameNoExternalInterop(_asyncAwaitMember), + asyncReturn: _emitTopLevelNameNoExternalInterop(_asyncReturnMember), + asyncRethrow: _emitTopLevelNameNoExternalInterop(_asyncRethrowMember), + completerFactory: _emitTopLevelNameNoExternalInterop( + _asyncMakeCompleterMember, + ), + completerFactoryTypeArguments: [_emitType(asyncType!)], + wrapBody: _emitTopLevelNameNoExternalInterop( + _asyncWrapJsFunctionMember, + ), + bodyName: bodyName, + ); case AsyncMarker.SyncStar: asyncRewriter = SyncStarRewriter( - makeSyncStarIterable: - _emitTopLevelNameNoExternalInterop(_syncStarMakeIterableMember), - syncStarIterableTypeArgument: _emitType(asyncType!), - iteratorCurrentValueProperty: _emitMemberName('_current', - member: _syncStarIteratorCurrentMember), - iteratorDatumProperty: - _emitMemberName('_datum', member: _syncStarIteratorDatumMember), - yieldStarSelector: _emitMemberName('_yieldStar', - member: _syncStarIteratorYieldStarMember), - bodyName: bodyName); + makeSyncStarIterable: _emitTopLevelNameNoExternalInterop( + _syncStarMakeIterableMember, + ), + syncStarIterableTypeArgument: _emitType(asyncType!), + iteratorCurrentValueProperty: _emitMemberName( + '_current', + member: _syncStarIteratorCurrentMember, + ), + iteratorDatumProperty: _emitMemberName( + '_datum', + member: _syncStarIteratorDatumMember, + ), + yieldStarSelector: _emitMemberName( + '_yieldStar', + member: _syncStarIteratorYieldStarMember, + ), + bodyName: bodyName, + ); case AsyncMarker.AsyncStar: asyncRewriter = AsyncStarRewriter( - asyncStarHelper: - _emitTopLevelNameNoExternalInterop(_asyncStarHelperMember), - streamOfController: _emitTopLevelNameNoExternalInterop( - _asyncStreamOfControllerMember), - newController: _emitTopLevelNameNoExternalInterop( - _asyncMakeAsyncStarStreamControllerMember), - newControllerTypeArguments: [_emitType(asyncType!)], - yieldExpression: - _emitStaticGet(_asyncIterationMarkerYieldSingleMember), - yieldStarExpression: - _emitStaticGet(_asyncIterationMarkerYieldStarMember), - wrapBody: - _emitTopLevelNameNoExternalInterop(_asyncWrapJsFunctionMember), - bodyName: bodyName); + asyncStarHelper: _emitTopLevelNameNoExternalInterop( + _asyncStarHelperMember, + ), + streamOfController: _emitTopLevelNameNoExternalInterop( + _asyncStreamOfControllerMember, + ), + newController: _emitTopLevelNameNoExternalInterop( + _asyncMakeAsyncStarStreamControllerMember, + ), + newControllerTypeArguments: [_emitType(asyncType!)], + yieldExpression: _emitStaticGet( + _asyncIterationMarkerYieldSingleMember, + ), + yieldStarExpression: _emitStaticGet( + _asyncIterationMarkerYieldStarMember, + ), + wrapBody: _emitTopLevelNameNoExternalInterop( + _asyncWrapJsFunctionMember, + ), + bodyName: bodyName, + ); } if (asyncRewriter != null) { - return asyncRewriter.rewrite(fun, functionBody, functionEnd, - bodyPrefix: bodyPrefix); + return asyncRewriter.rewrite( + fun, + functionBody, + functionEnd, + bodyPrefix: bodyPrefix, + ); } else if (bodyPrefix != null) { fun.body.statements.insertAll(0, bodyPrefix); } return fun; } - js_ast.Parameter _emitParameter(VariableDeclaration node, - {bool withoutInitializer = false}) { + js_ast.Parameter _emitParameter( + VariableDeclaration node, { + bool withoutInitializer = false, + }) { var initializer = node.initializer; var id = _emitVariableDef(node); if (initializer == null || withoutInitializer) return id; return js_ast.DestructuredVariable( - name: id, defaultValue: _visitExpression(initializer)); + name: id, + defaultValue: _visitExpression(initializer), + ); } - List<js_ast.Parameter> _emitParameters(FunctionNode f, - {bool isForwarding = false}) { + List<js_ast.Parameter> _emitParameters( + FunctionNode f, { + bool isForwarding = false, + }) { // Destructure optional positional parameters in place. // Given: // - (arg1, arg2, [opt1, opt2 = def2]) @@ -4248,8 +4766,11 @@ // forwarded call not a parameter list. E.g., the second in: // - foo(arg1, opt1 = def1) => super(arg1, opt1). var positional = f.positionalParameters; - var result = List<js_ast.Parameter>.of(positional - .map((p) => _emitParameter(p, withoutInitializer: isForwarding))); + var result = List<js_ast.Parameter>.of( + positional.map( + (p) => _emitParameter(p, withoutInitializer: isForwarding), + ), + ); if (positional.isNotEmpty && f.requiredParameterCount == positional.length && positional.last.annotations.any(isJsRestAnnotation)) { @@ -4260,16 +4781,21 @@ } List<js_ast.Identifier> _emitTypeFormals( - List< /*TypeParameter | StructuralParameter */ Object> typeFormals) { - assert(typeFormals is List<TypeParameter> || - typeFormals is List<StructuralParameter>); + List< /*TypeParameter | StructuralParameter */ Object> typeFormals, + ) { + assert( + typeFormals is List<TypeParameter> || + typeFormals is List<StructuralParameter>, + ); return typeFormals .map((t) => _emitIdentifier(getTypeParameterName(t))) .toList(); } List<js_ast.Statement> _withCurrentFunction( - FunctionNode fn, List<js_ast.Statement> Function() action) { + FunctionNode fn, + List<js_ast.Statement> Function() action, + ) { var savedFunction = _currentFunction; _currentFunction = fn; _nullableInference.enterFunction(fn); @@ -4310,13 +4836,18 @@ /// Emits argument initializers, which handles optional/named args, as well /// as generic type checks needed due to our covariance. List<js_ast.Statement> _emitArgumentInitializers( - FunctionNode f, String? name) { + FunctionNode f, + String? name, + ) { var body = <js_ast.Statement>[]; _emitCovarianceBoundsCheck(f.typeParameters, body); void initParameter( - VariableDeclaration p, js_ast.Identifier jsParam, bool isOptional) { + VariableDeclaration p, + js_ast.Identifier jsParam, + bool isOptional, + ) { // When the parameter is covariant, insert the null check before the // covariant cast to avoid a TypeError when testing equality with null. if (name == '==') { @@ -4367,14 +4898,16 @@ var jsParam = _emitVariableDef(p); var paramName = _propertyName(p.name!); var defaultValue = _defaultParamValue(p); - body.add(js.statement('let # = # && # ? #.# : #;', [ - jsParam, - _namedArgumentTemp, - _namedArgumentProbe(paramName), - _namedArgumentTemp, - paramName, - defaultValue, - ])); + body.add( + js.statement('let # = # && # ? #.# : #;', [ + jsParam, + _namedArgumentTemp, + _namedArgumentProbe(paramName), + _namedArgumentTemp, + paramName, + defaultValue, + ]), + ); if (_checkParameters) { initParameter(p, jsParam, !p.isRequired); @@ -4399,8 +4932,9 @@ // JS interop members should not pass type arguments. !isJsMember(m) && !(m.enclosingLibrary.importUri.isScheme('dart') && - m.annotations.any((a) => - isBuiltinAnnotation(a, '_js_helper', 'NoReifyGeneric'))); + m.annotations.any( + (a) => isBuiltinAnnotation(a, '_js_helper', 'NoReifyGeneric'), + )); js_ast.Statement _nullParameterCheck(js_ast.Expression param) { var call = _runtimeCall('argumentError((#))', [param]); @@ -4426,10 +4960,13 @@ : js.call('# in #', [propertyName, _namedArgumentTemp]); void _emitCovarianceBoundsCheck( - List< /* TypeParameter | StructuralParameter */ Object> typeFormals, - List<js_ast.Statement> body) { - assert(typeFormals is List<TypeParameter> || - typeFormals is List<StructuralParameter>); + List< /* TypeParameter | StructuralParameter */ Object> typeFormals, + List<js_ast.Statement> body, + ) { + assert( + typeFormals is List<TypeParameter> || + typeFormals is List<StructuralParameter>, + ); for (var t in typeFormals) { bool? isCovariantByClass; DartType bound; @@ -4444,18 +4981,22 @@ t as StructuralParameter; bound = t.bound.extensionTypeErasure; name = t.name!; - typeParameterType = - StructuralParameterType(t, Nullability.undetermined); + typeParameterType = StructuralParameterType( + t, + Nullability.undetermined, + ); } if (isCovariantByClass != null && isCovariantByClass && !_types.isTop(bound)) { - body.add(_runtimeStatement('checkTypeBound(#, #, #)', [ - _emitType(typeParameterType), - _emitType(bound), - _propertyName(name) - ])); + body.add( + _runtimeStatement('checkTypeBound(#, #, #)', [ + _emitType(typeParameterType), + _emitType(bound), + _propertyName(name), + ]), + ); } } } @@ -4542,8 +5083,10 @@ } if (node is AsExpression && node.isTypeError) { - assert(node.getStaticType(_staticTypeContext) == - _types.coreTypes.boolNonNullableRawType); + assert( + node.getStaticType(_staticTypeContext) == + _types.coreTypes.boolNonNullableRawType, + ); return _runtimeCall('dtest(#)', [_visitExpression(node.operand)]); } @@ -4602,8 +5145,12 @@ try { var loc = _component.getLocation(fileUri, offset); if (loc == null || loc.line < 0) return null; - return SourceLocation(offset, - sourceUrl: fileUri, line: loc.line - 1, column: loc.column - 1); + return SourceLocation( + offset, + sourceUrl: fileUri, + line: loc.line - 1, + column: loc.column - 1, + ); } on StateError catch (_) { // TODO(jmesserly): figure out why this is throwing. Perhaps the file URI // and offset are mismatched and don't correspond to the same source? @@ -4620,7 +5167,10 @@ /// on the library/class, so their access expressions do not appear in the /// source code. HoverComment? _hoverComment( - js_ast.Expression expr, int offset, int nameLength) { + js_ast.Expression expr, + int offset, + int nameLength, + ) { var start = _toSourceLocation(offset); var end = _toSourceLocation(offset + nameLength); return start != null && end != null ? HoverComment(expr, start, end) : null; @@ -4658,8 +5208,10 @@ // slightly different (in Dart, there is a nested scope), but that's handled // by _emitSyncFunctionBody. var isScope = !identical(node.parent, _currentFunction); - return js_ast.Block(node.statements.map(_visitStatement).toList(), - isScope: isScope); + return js_ast.Block( + node.statements.map(_visitStatement).toList(), + isScope: isScope, + ); } @override @@ -4705,8 +5257,10 @@ if (assertLocation != null) { var fileUri = assertLocation.file; var source = node.enclosingComponent!.uriToSource[fileUri]!.text; - conditionSource = - source.substring(node.conditionStartOffset, node.conditionEndOffset); + conditionSource = source.substring( + node.conditionStartOffset, + node.conditionEndOffset, + ); // Assertions that appear in debugger expressions have a synthetic Uri // that is different than the current library where the expression will // be evaluated. @@ -4734,7 +5288,7 @@ js.number(location == null ? -1 : location.line + 1), js.number(location == null ? -1 : location.column + 1), js.escapedString(conditionSource), - ]) + ]), ]); } @@ -4841,7 +5395,9 @@ } T _translateLoop<T extends js_ast.Statement>( - Statement node, T Function() action) { + Statement node, + T Function() action, + ) { List<LabeledStatement>? savedBreakTargets; if (_currentBreakTargets.isNotEmpty && _effectiveTargets[_currentBreakTargets.first] != node) { @@ -4882,8 +5438,10 @@ js_ast.Statement visitForStatement(ForStatement node) { return _translateLoop(node, () { js_ast.VariableInitialization emitForInitializer(VariableDeclaration v) => - js_ast.VariableInitialization(_emitVariableDef(v), - _visitInitializer(v.initializer, v.annotations)); + js_ast.VariableInitialization( + _emitVariableDef(v), + _visitInitializer(v.initializer, v.annotations), + ); if (node.variables.any(containsFunctionExpression)) { return _rewriteAsWhile(node); @@ -4895,8 +5453,9 @@ js_ast.Expression? update; if (updates.isNotEmpty) { update = js_ast.Expression.binary( - updates.map(_visitExpression).toList(), ',') - .toVoidExpression(); + updates.map(_visitExpression).toList(), + ',', + ).toVoidExpression(); } var condition = node.condition != null ? _visitTest(node.condition!) : null; @@ -4907,13 +5466,13 @@ } /// Rewrites a `for(;;)` style loop as a while loop to produce the correct - /// semantics when loop variable initialziers contain function expressions + /// semantics when loop variable initializers contain function expressions /// that close over other loop variables. /// /// The Dart semantics expect that every loop iteration gets fresh loop /// variables that can be closed over. The initialization is only executed /// for the first iteration. In later iterations, the fresh loop variables are - /// initalized to the values from the end of the previous iteration. + /// initialized to the values from the end of the previous iteration. /// /// These semantics differ from JavaScript when there are closures capturing /// loop variables so the simple lowering doesn't work as expected. @@ -4963,55 +5522,65 @@ for (var variable in node.variables) js.statement('# = #;', [ loopVariableIds[variable]!, - _visitInitializer(variable.initializer, variable.annotations) + _visitInitializer(variable.initializer, variable.annotations), ]), ]); var prevInits = js_ast.Block([ // Intialize fresh loop variables with the value from the previous // iteration. for (var variable in node.variables) - js.statement('# = #;', - [loopVariableIds[variable], prevVariableTempIds[variable]]), + js.statement('# = #;', [ + loopVariableIds[variable], + prevVariableTempIds[variable], + ]), // Original update expressions. for (var update in node.updates) _visitExpression(update).toStatement(), ]); return js_ast.Block([ - // Create temporary variables for the intialization flag and previous + // Create temporary variables for the initialization flag and previous // loop variables. js_ast.VariableDeclarationList('let', [ - js_ast.VariableInitialization(initFlagTempId, js_ast.LiteralBool(true)), + js_ast.VariableInitialization( + initFlagTempId, + js_ast.LiteralBool(true), + ), for (var variable in node.variables) js_ast.VariableInitialization(prevVariableTempIds[variable]!, null), ]).toStatement(), // The for loop transformed into a while loop. js_ast.While( - js_ast.LiteralBool(true), - js_ast.Block([ - // Create fresh loop variables every iteration. - if (node.variables.isNotEmpty) - js_ast.VariableDeclarationList('let', [ - for (var variable in node.variables) - js_ast.VariableInitialization( - loopVariableIds[variable]!, null) - ]).toStatement(), - // Initialize loop variables. - js_ast.If(initFlagTempId, inits, prevInits), - // Loop condition guard. - if (node.condition != null) - js.statement('if (!#) break;', [_visitTest(node.condition!)]) - ..sourceInformation = _nodeStart(node.condition!), - // Original loop body. - _visitScope(_effectiveBodyOf(node, node.body)), - // Save previous loop variables - for (var variable in node.variables) - js.statement('# = #;', - [prevVariableTempIds[variable]!, _emitVariableRef(variable)]) - // Map these locations to the variable declaration so stepping - // in the Dart debugger doesn't jump to the previous line when - // stepping. - ..sourceInformation = _nodeStart(variable), - ])) - // The while loop gets mapped to the orginal for loop location. + js_ast.LiteralBool(true), + js_ast.Block([ + // Create fresh loop variables every iteration. + if (node.variables.isNotEmpty) + js_ast.VariableDeclarationList('let', [ + for (var variable in node.variables) + js_ast.VariableInitialization( + loopVariableIds[variable]!, + null, + ), + ]).toStatement(), + // Initialize loop variables. + js_ast.If(initFlagTempId, inits, prevInits), + // Loop condition guard. + if (node.condition != null) + js.statement('if (!#) break;', [_visitTest(node.condition!)]) + ..sourceInformation = _nodeStart(node.condition!), + // Original loop body. + _visitScope(_effectiveBodyOf(node, node.body)), + // Save previous loop variables + for (var variable in node.variables) + js.statement('# = #;', [ + prevVariableTempIds[variable]!, + _emitVariableRef(variable), + ]) + // Map these locations to the variable declaration so stepping + // in the Dart debugger doesn't jump to the previous line when + // stepping. + ..sourceInformation = _nodeStart(variable), + ]), + ) + // The while loop gets mapped to the original for loop location. ..sourceInformation = _nodeStart(node), ]) // Clear the source mapping on the outer block so it doesn't automatically @@ -5030,8 +5599,10 @@ var init = js.call('let #', _emitVariableDef(node.variable)); if (_annotatedNullCheck(node.variable.annotations)) { - body = js_ast.Block( - [_nullParameterCheck(_emitVariableRef(node.variable)), body]); + body = js_ast.Block([ + _nullParameterCheck(_emitVariableRef(node.variable)), + body, + ]); } if (node.variable.name != null && @@ -5039,7 +5610,7 @@ var temp = _emitScopedId('iter'); return js_ast.Block([ iterable.toVariableDeclaration(temp), - js_ast.ForOf(init, temp, body) + js_ast.ForOf(init, temp, body), ]); } return js_ast.ForOf(init, iterable, body); @@ -5064,15 +5635,19 @@ // // TODO(jmesserly): we may want a helper if these become common. For now the // full desugaring seems okay. - var streamIterator = - _coreTypes.nonNullableRawType(_asyncStreamIteratorClass); + var streamIterator = _coreTypes.nonNullableRawType( + _asyncStreamIteratorClass, + ); var streamIteratorRti = _emitType(streamIterator); var createStreamIter = js_ast.Call( - _emitConstructorName( - streamIterator, - _asyncStreamIteratorClass.procedures - .firstWhere((p) => p.isFactory && p.name.text == '')), - [streamIteratorRti, _visitExpression(node.iterable)]); + _emitConstructorName( + streamIterator, + _asyncStreamIteratorClass.procedures.firstWhere( + (p) => p.isFactory && p.name.text == '', + ), + ), + [streamIteratorRti, _visitExpression(node.iterable)], + ); var iter = _emitScopedId('iter'); @@ -5085,7 +5660,7 @@ ..sourceInformation = _nodeStart(node.variable), _emitVariableDef(node.variable), iter, - _visitStatement(node.body) + _visitStatement(node.body), ]); // Any label on the Dart loop statement should target the inner loop rather @@ -5096,14 +5671,17 @@ } var awaitForStmt = js_ast.Block([ - js_ast.ExpressionStatement(js_ast.VariableDeclarationList( - 'let', [js_ast.VariableInitialization(iter, createStreamIter)]) - ..sourceInformation = _nodeStart(node.iterable)), + js_ast.ExpressionStatement( + js_ast.VariableDeclarationList('let', [ + js_ast.VariableInitialization(iter, createStreamIter), + ]) + ..sourceInformation = _nodeStart(node.iterable), + ), js.statement('try { # } finally { #; }', [ loopStmt, js_ast.Await(js.call('#.cancel()', iter)) - ..sourceInformation = _nodeStart(node.variable) - ]) + ..sourceInformation = _nodeStart(node.variable), + ]), ], isScope: true); _currentContinueTargets = savedContinueTargets; @@ -5135,8 +5713,10 @@ _currentContinueTargets = []; for (var c in node.cases) { - var subcases = - _visitSwitchCase(c, lastSwitchCase: c == node.cases.last); + var subcases = _visitSwitchCase( + c, + lastSwitchCase: c == node.cases.last, + ); if (subcases.isNotEmpty) cases.addAll(subcases); } _currentContinueTargets = savedCurrentContinueTargets; @@ -5150,7 +5730,7 @@ var labeledStmt = js_ast.LabeledStatement(labelName, loopStmt); var block = js_ast.Block([ js.statement('let # = #', [labelState, switchExpr]), - labeledStmt + labeledStmt, ]); _inLabeledContinueSwitch = previous; return block; @@ -5172,8 +5752,10 @@ /// labeled continues. Dart permits the final case to implicitly break, but /// switch statements with labeled continues must explicitly break/continue /// to escape the surrounding infinite loop. - List<js_ast.SwitchClause> _visitSwitchCase(SwitchCase node, - {bool lastSwitchCase = false}) { + List<js_ast.SwitchClause> _visitSwitchCase( + SwitchCase node, { + bool lastSwitchCase = false, + }) { var cases = <js_ast.SwitchClause>[]; var emptyBlock = js_ast.Block.empty(); // TODO(jmesserly): make sure we are statically checking fall through @@ -5226,8 +5808,9 @@ return js_ast.Block([setStateStmt, continueStmt]); } return _emitInvalidNode( - node, 'see https://github.com/dart-lang/sdk/issues/29352') - .toStatement(); + node, + 'see https://github.com/dart-lang/sdk/issues/29352', + ).toStatement(); } @override @@ -5275,7 +5858,10 @@ @override js_ast.Statement visitTryCatch(TryCatch node) { return js_ast.Try( - _visitStatement(node.body).toBlock(), _visitCatch(node.catches), null); + _visitStatement(node.body).toBlock(), + _visitCatch(node.catches), + null, + ); } js_ast.Catch? _visitCatch(List<Catch> clauses) { @@ -5300,40 +5886,53 @@ js_ast.Statement catchBody = js_ast.Throw(_emitVariableRef(caughtError)); for (var clause in clauses.reversed) { catchBody = _catchClauseGuard( - clause, catchBody, exceptionParameter, stackTraceParameter); + clause, + catchBody, + exceptionParameter, + stackTraceParameter, + ); } var catchStatements = [ js.statement('let # = #', [ _emitVariableDef(exceptionParameter), - _runtimeCall('getThrown(#)', [_emitVariableRef(caughtError)]) + _runtimeCall('getThrown(#)', [_emitVariableRef(caughtError)]), ]), if (stackTraceParameter != null) js.statement('let # = #', [ _emitVariableDef(stackTraceParameter), - _runtimeCall('stackTrace(#)', [_emitVariableRef(caughtError)]) + _runtimeCall('stackTrace(#)', [_emitVariableRef(caughtError)]), ]), catchBody, ]; _rethrowParameter = savedRethrow; - return js_ast.Catch(_emitVariableDef(caughtError), - js_ast.Block(catchStatements, isScope: true)); + return js_ast.Catch( + _emitVariableDef(caughtError), + js_ast.Block(catchStatements, isScope: true), + ); } js_ast.Statement _catchClauseGuard( - Catch node, - js_ast.Statement otherwise, - VariableDeclaration exceptionParameter, - VariableDeclaration? stackTraceParameter) { + Catch node, + js_ast.Statement otherwise, + VariableDeclaration exceptionParameter, + VariableDeclaration? stackTraceParameter, + ) { var body = <js_ast.Statement>[]; var vars = HashSet<String>(); void declareVariable( - VariableDeclaration? variable, VariableDeclaration? value) { + VariableDeclaration? variable, + VariableDeclaration? value, + ) { if (variable == null || value == null) return; vars.add(variable.name!); if (variable.name != value.name) { - body.add(js.statement('let # = #', - [_emitVariableDef(variable), _emitVariableRef(value)])); + body.add( + js.statement('let # = #', [ + _emitVariableDef(variable), + _emitVariableRef(value), + ]), + ); } } @@ -5347,8 +5946,10 @@ // Discard following clauses, if any, as they are unreachable. if (_types.isTop(guardType)) return then; - var condition = - _emitIsExpression(VariableGet(exceptionParameter), guardType); + var condition = _emitIsExpression( + VariableGet(exceptionParameter), + guardType, + ); return js_ast.If(condition, then, otherwise) ..sourceInformation = _nodeStart(node); } @@ -5356,8 +5957,9 @@ @override js_ast.Statement visitTryFinally(TryFinally node) { var body = _visitStatement(node.body); - var finallyBlock = - _superDisallowed(() => _visitStatement(node.finalizer).toBlock()); + var finallyBlock = _superDisallowed( + () => _visitStatement(node.finalizer).toBlock(), + ); if (body is js_ast.Try && body.finallyPart == null) { // Kernel represents Dart try/catch/finally as try/catch nested inside of @@ -5371,7 +5973,9 @@ @override js_ast.Statement visitYieldStatement(YieldStatement node) { return js_ast.DartYield( - _visitExpression(node.expression), node.isYieldStar); + _visitExpression(node.expression), + node.isYieldStar, + ); } @override @@ -5379,8 +5983,10 @@ // TODO(jmesserly): casts are sometimes required here. // Kernel does not represent these explicitly. var v = _emitVariableDef(node); - return js.statement('let # = #;', - [v, _visitInitializer(node.initializer, node.annotations)]); + return js.statement('let # = #;', [ + v, + _visitInitializer(node.initializer, node.annotations), + ]); } @override @@ -5394,9 +6000,10 @@ if (_reifyFunctionType(func)) { declareFn = js_ast.Block([ declareFn, - _emitFunctionTagged(_emitVariableRef(node.variable), - func.computeThisFunctionType(Nullability.nonNullable)) - .toStatement() + _emitFunctionTagged( + _emitVariableRef(node.variable), + func.computeThisFunctionType(Nullability.nonNullable), + ).toStatement(), ]); } return declareFn; @@ -5416,7 +6023,8 @@ var id = _emitVariableRef(v); if (id.name == v.name) { id = id.withSourceInformation( - _variableSpan(node.fileOffset, v.name!.length)); + _variableSpan(node.fileOffset, v.name!.length), + ); } return id; } @@ -5455,7 +6063,9 @@ var name = _debuggerFriendlyTemporaryVariableName(v); name ??= 't\$${_tempVariables.length}'; return _tempVariables.putIfAbsent( - v, () => _emitScopedId(name!, needsCapture: true)); + v, + () => _emitScopedId(name!, needsCapture: true), + ); } var name = v.name!; if (isLateLoweredLocal(v)) { @@ -5466,7 +6076,8 @@ name = extractLocalNameFromLateLoweredLocal(name); } return js_ast.ScopedId.from( - _variableTempIds[v] ??= _emitScopedId(name, needsCapture: true)); + _variableTempIds[v] ??= _emitScopedId(name, needsCapture: true), + ); } /// Emits the declaration of a variable. @@ -5482,9 +6093,10 @@ js_ast.Statement? _initLetVariables() { var letVars = _letVariables!; if (letVars.isEmpty) return null; - var result = js_ast.VariableDeclarationList('let', - letVars.map((v) => js_ast.VariableInitialization(v, null)).toList()) - .toStatement(); + var result = js_ast.VariableDeclarationList( + 'let', + letVars.map((v) => js_ast.VariableInitialization(v, null)).toList(), + ).toStatement(); letVars.clear(); return result; } @@ -5496,9 +6108,9 @@ // hand side, to help normalize the inconsistent locations of the CFE // lowerings for ++x, x++, x+=, etc. // See https://github.com/dart-lang/sdk/issues/55691. - return _visitExpression(node.value) - .toAssignExpression(_emitVariableRef(node.variable)) - ..sourceInformation = _nodeStart(node.value); + return _visitExpression(node.value).toAssignExpression( + _emitVariableRef(node.variable), + )..sourceInformation = _nodeStart(node.value); } @override @@ -5509,7 +6121,9 @@ } js_ast.Expression _emitDynamicGet( - js_ast.Expression receiver, js_ast.Expression memberName) => + js_ast.Expression receiver, + js_ast.Expression memberName, + ) => _runtimeCall('dload$_replSuffix(#, #)', [receiver, memberName]); @override @@ -5537,18 +6151,22 @@ return _runtimeCall('#(#)', [memberName, jsReceiver]); } // Otherwise generate this as a normal typed property get. - var jsMemberName = - _emitMemberName(memberName, member: node.interfaceTarget); + var jsMemberName = _emitMemberName( + memberName, + member: node.interfaceTarget, + ); var instanceGet = js_ast.PropertyAccess(jsReceiver, jsMemberName); if (_shouldRewriteInvocationWithHotReloadChecks(node.interfaceTarget)) { instanceGet.sourceInformation = _nodeStart(node); // Since there are no arguments (unlike methods) the dynamic get path can // be reused for the hot reload checks on a getter. var checkedGet = _emitCast( - _emitDynamicGet( - _visitExpression(receiver), _emitMemberName(memberName)), - node.resultType) - ..sourceInformation = _nodeStart(node); + _emitDynamicGet( + _visitExpression(receiver), + _emitMemberName(memberName), + ), + node.resultType, + )..sourceInformation = _nodeStart(node); return _emitHotReloadSafeInvocation(instanceGet, checkedGet); } return _isNullCheckableJsInterop(node.interfaceTarget) @@ -5565,9 +6183,13 @@ _emitRecordElementGet(node.receiver, node.name); js_ast.Expression _emitRecordElementGet( - Expression receiver, String elementName) => + Expression receiver, + String elementName, + ) => js_ast.PropertyAccess( - _visitExpression(receiver), _emitMemberName(elementName)); + _visitExpression(receiver), + _emitMemberName(elementName), + ); @override js_ast.Expression visitInstanceTearOff(InstanceTearOff node) { @@ -5597,8 +6219,10 @@ } var jsPropertyAccess = js_ast.PropertyAccess(jsReceiver, jsMemberName); return isJsMember(member) - ? _runtimeCall('tearoffInterop(#, #)', - [jsPropertyAccess, js.boolean(_isNullCheckableJsInterop(member))]) + ? _runtimeCall('tearoffInterop(#, #)', [ + jsPropertyAccess, + js.boolean(_isNullCheckableJsInterop(member)), + ]) : jsPropertyAccess; } @@ -5612,7 +6236,7 @@ return _runtimeCall('dput$_replSuffix(#, #, #)', [ _visitExpression(node.receiver), _emitMemberName(node.name.text), - _visitExpression(node.value) + _visitExpression(node.value), ]); } @@ -5623,7 +6247,7 @@ return js.call('#.# = #', [ _visitExpression(node.receiver), _emitMemberName(node.name.text, member: target), - _visitExpression(value) + _visitExpression(value), ]); } @@ -5716,7 +6340,8 @@ @override js_ast.Expression visitAbstractSuperPropertyGet( - AbstractSuperPropertyGet node) { + AbstractSuperPropertyGet node, + ) { return _emitSuperPropertyGet(node.interfaceTarget); } @@ -5735,8 +6360,10 @@ if (!mixedInClass.isAnonymousMixin) { mixinName += '#${baseClass.name}'; } - return _mixinCache - .putIfAbsent((mixedInClass, baseClass), () => _emitScopedId(mixinName)); + return _mixinCache.putIfAbsent(( + mixedInClass, + baseClass, + ), () => _emitScopedId(mixinName)); } js_ast.Expression _emitSuperPropertyGet(Member target) { @@ -5751,14 +6378,19 @@ var mixinId = _emitMixinId(enclosingClass, enclosingClass); var enclosingLibrary = _emitLibraryName(getLibrary(enclosingClass)); supertypeReference = js_ast.PropertyAccess( - enclosingLibrary, js.string(mixinId.name)); + enclosingLibrary, + js.string(mixinId.name), + ); } else { - supertypeReference = - _emitTopLevelNameNoExternalInterop(enclosingClass); + supertypeReference = _emitTopLevelNameNoExternalInterop( + enclosingClass, + ); } } - return _runtimeCall( - 'superTearoff(this, #, #)', [supertypeReference, jsName]); + return _runtimeCall('superTearoff(this, #, #)', [ + supertypeReference, + jsName, + ]); } else { return _emitSuperTearoffFromDisallowedContext(target); } @@ -5768,7 +6400,8 @@ @override js_ast.Expression visitAbstractSuperPropertySet( - AbstractSuperPropertySet node) { + AbstractSuperPropertySet node, + ) { return _emitSuperPropertySet(node.interfaceTarget, node.value); } @@ -5808,8 +6441,11 @@ var result = js.call('#.#', [context, property]); if (_reifyTearoff(target)) { var targetLabel = js.string(fullyResolvedTargetLabel(target)); - return _runtimeCall( - 'staticTearoff(#, #, #)', [context, targetLabel, property]); + return _runtimeCall('staticTearoff(#, #, #)', [ + context, + targetLabel, + property, + ]); } return result; } @@ -5825,7 +6461,10 @@ @override js_ast.Expression visitDynamicInvocation(DynamicInvocation node) { return _emitDynamicInvocation( - node.receiver, node.name.text, node.arguments); + node.receiver, + node.name.text, + node.arguments, + ); } @override @@ -5840,7 +6479,9 @@ return _emitDynamicInvocation(node.receiver, name, node.arguments); } return js_ast.Call( - _visitExpression(node.receiver), _emitArgumentList(node.arguments)); + _visitExpression(node.receiver), + _emitArgumentList(node.arguments), + ); } @override @@ -5853,14 +6494,18 @@ @override js_ast.Expression visitInstanceGetterInvocation( - InstanceGetterInvocation node) { + InstanceGetterInvocation node, + ) { if (node.functionType == null) { // A `null` here implies the receiver must be typed as `dynamic` or // `Function`. There isn't any more type information available at compile // time to know this invocation is sound so a dynamic call will handle the // checks at runtime. return _emitDynamicInvocation( - node.receiver, node.name.text, node.arguments); + node.receiver, + node.name.text, + node.arguments, + ); } var getterInvocation = _emitInstanceGetterInvocation(node); return _isNullCheckableJsInterop(node.interfaceTarget) @@ -5869,10 +6514,13 @@ } js_ast.Expression _emitInstanceGetterInvocation( - InstanceGetterInvocation node) { + InstanceGetterInvocation node, + ) { var receiver = _visitExpression(node.receiver); - var arguments = - _emitArgumentList(node.arguments, target: node.interfaceTarget); + var arguments = _emitArgumentList( + node.arguments, + target: node.interfaceTarget, + ); if (node.name.text == 'call') { // Erasing the extension types here to support existing callable behavior // on the old style JS interop types that are callable. This should be @@ -5885,8 +6533,10 @@ return js_ast.Call(receiver, arguments); } } - var memberName = - _emitMemberName(node.name.text, member: node.interfaceTarget); + var memberName = _emitMemberName( + node.name.text, + member: node.interfaceTarget, + ); // We must erase the extension type to potentially find the `call` method. // If the extension type has a runtime representation with a `call`: // @@ -5917,19 +6567,27 @@ assert(node.name.text == 'call'); final localName = VariableGet(node.variable)..fileOffset = node.fileOffset; return js_ast.Call( - _visitExpression(localName), _emitArgumentList(node.arguments)); + _visitExpression(localName), + _emitArgumentList(node.arguments), + ); } @override js_ast.Expression visitEqualsCall(EqualsCall node) { - return _emitEqualityOperator(node.left, node.interfaceTarget, node.right, - negated: false); + return _emitEqualityOperator( + node.left, + node.interfaceTarget, + node.right, + negated: false, + ); } @override js_ast.Expression visitEqualsNull(EqualsNull node) { - return _emitCoreIdenticalCall([node.expression, NullLiteral()], - negated: false); + return _emitCoreIdenticalCall([ + node.expression, + NullLiteral(), + ], negated: false); } js_ast.Expression _emitInstanceInvocation(InstanceInvocation node) { @@ -5980,7 +6638,11 @@ return _emitUnaryOperator(receiver, target, node); } else if (argLength == 1) { return _emitBinaryOperator( - receiver, target, arguments.positional[0], node); + receiver, + target, + arguments.positional[0], + node, + ); } } var jsReceiver = _visitExpression(receiver); @@ -6017,7 +6679,10 @@ /// or `dgsend` to perform dynamic checks before invoking [memberName] on /// [receiver] and passing [arguments]. js_ast.Expression _emitDynamicInvocation( - Expression receiver, String memberName, Arguments arguments) { + Expression receiver, + String memberName, + Arguments arguments, + ) { var jsArgs = [_visitExpression(receiver)]; String jsCode; var (:typeArguments, :positionalArguments, :namedArguments) = @@ -6065,7 +6730,10 @@ } js_ast.Expression _emitUnaryOperator( - Expression expr, Member? target, InvocationExpression node) { + Expression expr, + Member? target, + InvocationExpression node, + ) { var op = node.name.text; if (target != null) { var dispatchType = _coreTypes.nonNullableRawType(target.enclosingClass!); @@ -6073,7 +6741,9 @@ if (op == '~') { if (_typeRep.isNumber(dispatchType)) { return _coerceBitOperationResultToUnsigned( - node, js.call('~#', _notNull(expr))); + node, + js.call('~#', _notNull(expr)), + ); } return _emitOperatorCall(expr, target, op, []); } @@ -6089,7 +6759,9 @@ /// JavaScript operations interpret their operands as signed and generate /// signed results. js_ast.Expression _coerceBitOperationResultToUnsigned( - Expression node, js_ast.Expression uncoerced) { + Expression node, + js_ast.Expression uncoerced, + ) { // Don't coerce if the parent will coerce. var parent = node.parent; if (parent is InvocationExpression && _nodeIsBitwiseOperation(parent)) { @@ -6224,8 +6896,8 @@ } var rightWidth = bitWidth(right, depth); if (rightWidth <= 5) { - // e.g. `1 << (x & 7)` has a rightWidth of 3, so shifts by up to - // (1 << 3) - 1 == 7 bits. + // e.g. `1 << (x & 7)` has a rightWidth of 3, so shifts by up + // to (1 << 3) - 1 == 7 bits. return min(MAX, leftWidth + ((1 << rightWidth) - 1)); } return MAX; @@ -6242,8 +6914,12 @@ return bitWidth(expr, 0) < 32; } - js_ast.Expression _emitBinaryOperator(Expression left, Member? target, - Expression right, InvocationExpression node) { + js_ast.Expression _emitBinaryOperator( + Expression left, + Member? target, + Expression right, + InvocationExpression node, + ) { var op = node.name.text; if (op == '==') return _emitEqualityOperator(left, target, right); @@ -6286,7 +6962,7 @@ return js.call('(# / #).#()', [ _notNull(left), _notNull(right), - _emitMemberName('truncate', memberClass: targetClass) + _emitMemberName('truncate', memberClass: targetClass), ]); case '%': @@ -6317,8 +6993,9 @@ if (_isDefinitelyNonNegative(left) && shiftCount != null) { return binary('# >>> #'); } - // If the context selects out only bits that can't be affected by the - // sign position we can use any JavaScript shift, `(x >> 6) & 3`. + // If the context selects out only bits that can't be affected by + // the sign position we can use any JavaScript shift, + // `(x >> 6) & 3`. if (shiftCount != null && _parentMasksToWidth(node, 31 - shiftCount)) { return binary('# >> #'); @@ -6327,13 +7004,15 @@ case '<<': if (_is31BitUnsigned(node)) { - // Result is 31 bit unsigned which implies the shift count was small - // enough not to pollute the sign bit. + // Result is 31 bit unsigned which implies the shift count was + // small enough not to pollute the sign bit. return binary('# << #'); } if (_asIntInRange(right, 0, 31) != null) { return _coerceBitOperationResultToUnsigned( - node, binary('# << #')); + node, + binary('# << #'), + ); } return _emitOperatorCall(left, target, op, [right]); @@ -6354,8 +7033,11 @@ } js_ast.Expression _emitEqualityOperator( - Expression left, Member? target, Expression right, - {bool negated = false}) { + Expression left, + Member? target, + Expression right, { + bool negated = false, + }) { var targetClass = target?.enclosingClass; var leftType = left.getStaticType(_staticTypeContext).extensionTypeErasure; @@ -6393,15 +7075,17 @@ // The LHS isn't guaranteed to have an equals method we need to use a // runtime helper. return js.call(negated ? '!#' : '#', [ - _runtimeCall( - 'equals(#, #)', [_visitExpression(left), _visitExpression(right)]) + _runtimeCall('equals(#, #)', [ + _visitExpression(left), + _visitExpression(right), + ]), ]); } // Otherwise it is safe to call the equals method on the LHS directly. return js.call(negated ? '!#[#](#)' : '#[#](#)', [ _visitExpression(left), _emitMemberName('==', memberClass: targetClass), - _visitExpression(right) + _visitExpression(right), ]); } @@ -6411,7 +7095,11 @@ /// `obj.name(args)` because that could be a getter followed by a call. /// See [visitMethodInvocation]. js_ast.Expression _emitOperatorCall( - Expression receiver, Member? target, String name, List<Expression> args) { + Expression receiver, + Member? target, + String name, + List<Expression> args, + ) { // TODO(jmesserly): calls that don't pass `element` are probably broken for // `super` calls from disallowed super locations. var memberName = _emitMemberName(name, member: target); @@ -6419,26 +7107,32 @@ // dynamic dispatch var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name]; if (dynamicHelper != null) { - return _runtimeCall('$dynamicHelper(#, #)', - [_visitExpression(receiver), _visitExpressionList(args)]); + return _runtimeCall('$dynamicHelper(#, #)', [ + _visitExpression(receiver), + _visitExpressionList(args), + ]); } else { return _runtimeCall('dsend(#, #, [#])', [ _visitExpression(receiver), memberName, - _visitExpressionList(args) + _visitExpressionList(args), ]); } } // Generic dispatch to a statically known method. - return js.call('#.#(#)', - [_visitExpression(receiver), memberName, _visitExpressionList(args)]); + return js.call('#.#(#)', [ + _visitExpression(receiver), + memberName, + _visitExpressionList(args), + ]); } // TODO(jmesserly): optimize super operators for kernel @override js_ast.Expression visitAbstractSuperMethodInvocation( - AbstractSuperMethodInvocation node) { + AbstractSuperMethodInvocation node, + ) { return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments); } @@ -6448,9 +7142,13 @@ } js_ast.Expression _emitSuperMethodInvocation( - Member target, Arguments arguments) { + Member target, + Arguments arguments, + ) { return js_ast.Call( - _emitSuperTarget(target), _emitArgumentList(arguments, target: target)); + _emitSuperTarget(target), + _emitArgumentList(arguments, target: target), + ); } /// Emits the [js_ast.PropertyAccess] for accessors or method calls to @@ -6484,17 +7182,24 @@ var jsMethod = _superHelpers.putIfAbsent('$lookupPrefix$name', () { var isAccessor = member is Procedure ? member.isAccessor : true; if (isAccessor) { - assert(member is Procedure - ? member.isSetter == setter - : !setter || !(member as Field).isFinal); + assert( + member is Procedure + ? member.isSetter == setter + : !setter || !(member as Field).isFinal, + ); var fn = js.fun( - setter - ? 'function(x) { super[#] = x; }' - : 'function() { return super[#]; }', - [jsName]); + setter + ? 'function(x) { super[#] = x; }' + : 'function() { return super[#]; }', + [jsName], + ); - return js_ast.Method(_emitScopedId(name), fn, - isGetter: !setter, isSetter: setter); + return js_ast.Method( + _emitScopedId(name), + fn, + isGetter: !setter, + isSetter: setter, + ); } else { var function = member.function; var params = [ @@ -6504,8 +7209,11 @@ if (function.namedParameters.isNotEmpty) _namedArgumentTemp, ]; - var fn = js.fun( - 'function(#) { return super[#](#); }', [params, jsName, params]); + var fn = js.fun('function(#) { return super[#](#); }', [ + params, + jsName, + params, + ]); name = js_ast.friendlyNameForDartOperator[name] ?? name; return js_ast.Method(_emitScopedId(name), fn); } @@ -6648,19 +7356,22 @@ var extractionType = node.arguments.types.single; if (extractionType is! InterfaceType) { throw UnsupportedError( - 'Type arguments can only be extracted from interface types: ' - 'found $extractionType (${extractionType.runtimeType}) at ' - '${node.location}'); + 'Type arguments can only be extracted from interface types: ' + 'found $extractionType (${extractionType.runtimeType}) at ' + '${node.location}', + ); } var extractionTypeParameters = extractionType.classNode.typeParameters; if (extractionTypeParameters.isEmpty) { throw UnsupportedError( - 'The extraction type must have type arguments to be extracted: ' - 'found $extractionType (${extractionType.runtimeType}) at ' - '${node.location}'); + 'The extraction type must have type arguments to be extracted: ' + 'found $extractionType (${extractionType.runtimeType}) at ' + '${node.location}', + ); } - var extractionTypeParameterNames = extractionTypeParameters - .map((p) => '${extractionType.classNode.name}.${p.name!}'); + var extractionTypeParameterNames = extractionTypeParameters.map( + (p) => '${extractionType.classNode.name}.${p.name!}', + ); var instance = node.arguments.positional.first.accept(this); var function = node.arguments.positional.last.accept(this); var extractedTypeArgs = js_ast.ArrayInitializer([ @@ -6668,8 +7379,8 @@ js.call('#.#(#, "$recipe")', [ _emitLibraryName(_rtiLibrary), _emitMemberName('evalInInstance', memberClass: _rtiClass), - instance - ]) + instance, + ]), ]); return _runtimeCall('dgcall(#, #, [])', [function, extractedTypeArgs]); } @@ -6709,8 +7420,9 @@ } if (type is! InterfaceType) { throw UnsupportedError( - 'JS_CLASS_REF only supports interface types: found $type ' - '(${type.runtimeType}) at ${node.location}'); + 'JS_CLASS_REF only supports interface types: found $type ' + '(${type.runtimeType}) at ${node.location}', + ); } return _emitTopLevelName(type.classNode); } @@ -6731,7 +7443,8 @@ // extra information recorded. js.boolean(true), _ => throw UnsupportedError( - 'Unknown JS_GET_FLAG "$value" at ${node.location}') + 'Unknown JS_GET_FLAG "$value" at ${node.location}', + ), }; } } else if (args.length == 2) { @@ -6774,8 +7487,10 @@ if (name == '_jsInstanceOf' && type is InterfaceType && type.typeArguments.isEmpty) { - return js.call('# instanceof #', - [_visitExpression(firstArg), _emitTopLevelName(type.classNode)]); + return js.call('# instanceof #', [ + _visitExpression(firstArg), + _emitTopLevelName(type.classNode), + ]); } } } @@ -6783,15 +7498,19 @@ var name = target.name.text; if (name == 'jsObjectGetPrototypeOf') { var obj = node.arguments.positional.single; - return _emitJSObjectGetPrototypeOf(_visitExpression(obj), - fullyQualifiedName: false); + return _emitJSObjectGetPrototypeOf( + _visitExpression(obj), + fullyQualifiedName: false, + ); } if (name == 'jsObjectSetPrototypeOf') { var obj = node.arguments.positional.first; var prototype = node.arguments.positional.last; return _emitJSObjectSetPrototypeOf( - _visitExpression(obj), _visitExpression(prototype), - fullyQualifiedName: false); + _visitExpression(obj), + _visitExpression(prototype), + fullyQualifiedName: false, + ); } } if (target.isExternal && @@ -6801,9 +7520,13 @@ // and factories have named parameters. assert(target.function.positionalParameters.isEmpty); return _emitObjectLiteral( - Arguments(node.arguments.positional, - types: node.arguments.types, named: node.arguments.named), - target); + Arguments( + node.arguments.positional, + types: node.arguments.types, + named: node.arguments.named, + ), + target, + ); } if (target == _coreTypes.identicalProcedure) { return _emitCoreIdenticalCall(node.arguments.positional); @@ -6824,13 +7547,18 @@ var name = target.name.text; if (name == '_getPropertyTrustType') { return js_ast.PropertyAccess( - _visitExpression(node.arguments.positional[0]), - _visitExpression(node.arguments.positional[1])); + _visitExpression(node.arguments.positional[0]), + _visitExpression(node.arguments.positional[1]), + ); } else if (name == '_setPropertyUnchecked') { - return _visitExpression(node.arguments.positional[2]) - .toAssignExpression(js_ast.PropertyAccess( - _visitExpression(node.arguments.positional[0]), - _visitExpression(node.arguments.positional[1]))); + return _visitExpression( + node.arguments.positional[2], + ).toAssignExpression( + js_ast.PropertyAccess( + _visitExpression(node.arguments.positional[0]), + _visitExpression(node.arguments.positional[1]), + ), + ); } else if (_callMethodUncheckedRegex.hasMatch(name)) { // Note that we don't lower `_callMethodTrustType`. This is because it // uses `assertInterop` checks. @@ -6842,10 +7570,12 @@ args.add(_visitExpression(node.arguments.positional[i])); } js_ast.Expression call = js_ast.Call( - js_ast.PropertyAccess( - _visitExpression(node.arguments.positional[0]), - _visitExpression(node.arguments.positional[1])), - args); + js_ast.PropertyAccess( + _visitExpression(node.arguments.positional[0]), + _visitExpression(node.arguments.positional[1]), + ), + args, + ); if (!trustType) { call = _emitCast(call, node.arguments.types[0]); } @@ -6858,8 +7588,9 @@ args.add(_visitExpression(node.arguments.positional[i])); } return _emitCast( - js_ast.New(_visitExpression(node.arguments.positional[0]), args), - node.arguments.types[0]); + js_ast.New(_visitExpression(node.arguments.positional[0]), args), + node.arguments.types[0], + ); } } @@ -6869,10 +7600,11 @@ ..sourceInformation = _nodeStart(node); if (_shouldRewriteInvocationWithHotReloadChecks(target)) { var checkedCall = _rewriteInvocationWithHotReloadChecks( - target, - node.arguments, - node.getStaticType(_staticTypeContext), - _nodeStart(node)); + target, + node.arguments, + node.getStaticType(_staticTypeContext), + _nodeStart(node), + ); // As an optimization, avoid extra checks when the invocation code was // compiled in the same generation that it is running. return _emitHotReloadSafeInvocation(staticCall, checkedCall); @@ -6892,14 +7624,18 @@ target != _assertInteropMethod; js_ast.Expression _emitHotReloadSafeInvocation( - js_ast.Expression uncheckedCall, js_ast.Expression checkedCall) { + js_ast.Expression uncheckedCall, + js_ast.Expression checkedCall, + ) { var generationCheck = js.call('# === #', [ js.number(_hotReloadGeneration), - _runtimeCall('global.dartDevEmbedder.hotReloadGeneration') + _runtimeCall('global.dartDevEmbedder.hotReloadGeneration'), ]); return js_ast.InvocationWithHotReloadChecks( - generationCheck, uncheckedCall, checkedCall) - ..sourceInformation = continueSourceMap; + generationCheck, + uncheckedCall, + checkedCall, + )..sourceInformation = continueSourceMap; } /// Rewrites an invocation of [target] that is statically sound at compile @@ -6917,10 +7653,11 @@ /// The resulting expression for the validated call site will receive the /// [originalCallSiteSourceLocation]. js_ast.Expression _rewriteInvocationWithHotReloadChecks( - Member target, - Arguments arguments, - DartType expectedReturnType, - SourceLocation? originalCallSiteSourceLocation) { + Member target, + Arguments arguments, + DartType expectedReturnType, + SourceLocation? originalCallSiteSourceLocation, + ) { var hoistedPositionalVariables = <js_ast.Expression>[]; var hoistedNamedVariables = <String, js_ast.Expression>{}; js_ast.Expression? letAssignments; @@ -6970,21 +7707,23 @@ // TODO(nshahan): Remove this check if we stop rewriting calls to SDK // functions. if (_reifyGenericFunction(target)) - for (var typeArgument in arguments.types) _emitType(typeArgument) + for (var typeArgument in arguments.types) _emitType(typeArgument), ]; - var correctnessCheck = - _runtimeCall('hotReloadCorrectnessChecks(#, #, #, #, #)', [ - jsTarget.receiver, - jsTarget.selector, - js_ast.ArrayInitializer(jsTypeArguments), - js_ast.ArrayInitializer(hoistedPositionalVariables), - hoistedNamedVariables.isEmpty - ? js_ast.LiteralNull() - : js_ast.ObjectInitializer([ - for (var e in hoistedNamedVariables.entries) - js_ast.Property(js.string(e.key), e.value) - ]) - ]); + var correctnessCheck = _runtimeCall( + 'hotReloadCorrectnessChecks(#, #, #, #, #)', + [ + jsTarget.receiver, + jsTarget.selector, + js_ast.ArrayInitializer(jsTypeArguments), + js_ast.ArrayInitializer(hoistedPositionalVariables), + hoistedNamedVariables.isEmpty + ? js_ast.LiteralNull() + : js_ast.ObjectInitializer([ + for (var e in hoistedNamedVariables.entries) + js_ast.Property(js.string(e.key), e.value), + ]), + ], + ); var checkAssignment = js.call('# = #', [checkResult, correctnessCheck]); letAssignments = letAssignments == null ? checkAssignment @@ -6997,32 +7736,37 @@ if (hoistedNamedVariables.isNotEmpty) js_ast.ObjectInitializer([ for (var e in hoistedNamedVariables.entries) - js_ast.Property(js.string(e.key), e.value) - ]) + js_ast.Property(js.string(e.key), e.value), + ]), ]) ..sourceInformation = originalCallSiteSourceLocation; // Cast the result of the checked call or the value returned from a // `NoSuchMethod` invocation. return js_ast.Binary( - ',', - letAssignments, - js.call('# == # ? # : #', [ - checkResult, - _runtimeCall('validArgumentsSentinel'), - _emitCast(validatedCallSite, expectedReturnType), - _emitCast(checkResult, expectedReturnType) - ])); + ',', + letAssignments, + js.call('# == # ? # : #', [ + checkResult, + _runtimeCall('validArgumentsSentinel'), + _emitCast(validatedCallSite, expectedReturnType), + _emitCast(checkResult, expectedReturnType), + ]), + ); } - js_ast.Expression _emitJSObjectGetPrototypeOf(js_ast.Expression obj, - {required bool fullyQualifiedName}) => + js_ast.Expression _emitJSObjectGetPrototypeOf( + js_ast.Expression obj, { + required bool fullyQualifiedName, + }) => fullyQualifiedName ? _runtimeCall('global.Object.getPrototypeOf(#)', [obj]) : js.call('Object.getPrototypeOf(#)', obj); js_ast.Expression _emitJSObjectSetPrototypeOf( - js_ast.Expression obj, js_ast.Expression prototype, - {required bool fullyQualifiedName}) => + js_ast.Expression obj, + js_ast.Expression prototype, { + required bool fullyQualifiedName, + }) => fullyQualifiedName ? _runtimeCall('global.Object.setPrototypeOf(#, #)', [obj, prototype]) : js.call('Object.setPrototypeOf(#, #)', [obj, prototype]); @@ -7035,8 +7779,9 @@ js_ast.Node _emitDebuggerCall(StaticInvocation node) { var args = node.arguments.named; var isStatement = node.parent is ExpressionStatement; - var debuggerStatement = - js_ast.DebuggerStatement().withSourceInformation(_nodeStart(node)); + var debuggerStatement = js_ast.DebuggerStatement().withSourceInformation( + _nodeStart(node), + ); if (args.isEmpty) { // Inline `debugger()` with no arguments, as a statement if possible, // otherwise as an immediately invoked function. @@ -7068,8 +7813,10 @@ : js.call('#.when', js_ast.ObjectInitializer(jsArgs)); return isStatement ? js.statement('if (#) #;', [when, debuggerStatement]) - : js.call( - '# && (() => { #; return true })()', [when, debuggerStatement]); + : js.call('# && (() => { #; return true })()', [ + when, + debuggerStatement, + ]); } /// Emits the target of a [StaticInvocation], [StaticGet], or [StaticSet]. @@ -7088,11 +7835,15 @@ ? _emitStaticMemberName(target.name.text, target) : js.string(annotationName); return js_ast.PropertyAccess( - _runtimeCall('global.#', [nativeName[0]]), memberName); + _runtimeCall('global.#', [nativeName[0]]), + memberName, + ); } } - return js_ast.PropertyAccess(_emitStaticClassName(c, isExternal), - _emitStaticMemberName(target.name.text, target)); + return js_ast.PropertyAccess( + _emitStaticClassName(c, isExternal), + _emitStaticMemberName(target.name.text, target), + ); } return _emitTopLevelName(target); } @@ -7106,12 +7857,20 @@ /// Passing [target] when applicable allows for detection of an annotation to /// omit passing type parameters and to detect if positional arguments should /// be packaged to be passed to a JavaScript using an interop call. - List<js_ast.Expression> _emitArgumentList(Arguments node, - {bool types = true, Member? target}) { + List<js_ast.Expression> _emitArgumentList( + Arguments node, { + bool types = true, + Member? target, + }) { types = types && _reifyGenericFunction(target); - var (:typeArguments, :positionalArguments, :namedArguments) = - _emitArgumentGroups(node, - isJSInterop: target != null && isJsMember(target)); + var ( + :typeArguments, + :positionalArguments, + :namedArguments, + ) = _emitArgumentGroups( + node, + isJSInterop: target != null && isJsMember(target), + ); return [ if (types && typeArguments != null) ...typeArguments, if (positionalArguments != null) ...positionalArguments, @@ -7127,8 +7886,10 @@ /// /// When [isJSInterop] is `true` the positional arguments are packaged to /// be passed to JavaScript via an interop call. - _ArgumentGroups _emitArgumentGroups(Arguments node, - {required bool isJSInterop}) { + _ArgumentGroups _emitArgumentGroups( + Arguments node, { + required bool isJSInterop, + }) { var typeArguments = node.types.isEmpty ? null : [for (var typeArgument in node.types) _emitType(typeArgument)]; @@ -7152,12 +7913,14 @@ return ( typeArguments: typeArguments, positionalArguments: positionalArguments, - namedArguments: namedArguments + namedArguments: namedArguments, ); } - js_ast.Property _emitNamedExpression(NamedExpression arg, - [bool isJsInterop = false]) { + js_ast.Property _emitNamedExpression( + NamedExpression arg, [ + bool isJsInterop = false, + ]) { var value = isJsInterop ? _assertInterop(arg.value) : arg.value; return js_ast.Property(_propertyName(arg.name), _visitExpression(value)); } @@ -7179,8 +7942,9 @@ } else { if (args.length > 2) { throw ArgumentError( - "Can't mix template args and string interpolation in JS calls: " - '`$node`'); + "Can't mix template args and string interpolation in JS calls: " + '`$node`', + ); } templateArgs = <Expression>[]; source = code.expressions.map((expression) { @@ -7217,8 +7981,10 @@ } } - assert(result is js_ast.Expression || - result is js_ast.Statement && node.parent is ExpressionStatement); + assert( + result is js_ast.Expression || + result is js_ast.Statement && node.parent is ExpressionStatement, + ); return result.withSourceInformation(_nodeStart(node)); } @@ -7241,22 +8007,29 @@ case JsGetName.OPERATOR_IS_PREFIX: return js.string(js_ast.FixedNames.operatorIsPrefix); case JsGetName.SIGNATURE_NAME: - return _runtimeCall( - '#', [js.string(js_ast.FixedNames.operatorSignature)]); + return _runtimeCall('#', [ + js.string(js_ast.FixedNames.operatorSignature), + ]); case JsGetName.RTI_NAME: return js.string(js_ast.FixedNames.rtiName); case JsGetName.FUTURE_CLASS_TYPE_NAME: return js.string( - _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.futureClass)); + _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.futureClass), + ); case JsGetName.LIST_CLASS_TYPE_NAME: return js.string( - _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.listClass)); + _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.listClass), + ); case JsGetName.RTI_FIELD_AS: - return _emitMemberName(js_ast.FixedNames.rtiAsField, - memberClass: _rtiClass); + return _emitMemberName( + js_ast.FixedNames.rtiAsField, + memberClass: _rtiClass, + ); case JsGetName.RTI_FIELD_IS: - return _emitMemberName(js_ast.FixedNames.rtiIsField, - memberClass: _rtiClass); + return _emitMemberName( + js_ast.FixedNames.rtiIsField, + memberClass: _rtiClass, + ); default: throw UnsupportedError('JsGetName has no name for "$name".'); } @@ -7283,11 +8056,13 @@ return '$enumName.$valueName'; } - JsGetName _asJsGetName(Field field) => JsGetName.values - .firstWhere((val) => val.toString() == _enumValueName(field)); + JsGetName _asJsGetName(Field field) => JsGetName.values.firstWhere( + (val) => val.toString() == _enumValueName(field), + ); - JsBuiltin _asJsBuiltin(Field field) => JsBuiltin.values - .firstWhere((val) => val.toString() == _enumValueName(field)); + JsBuiltin _asJsBuiltin(Field field) => JsBuiltin.values.firstWhere( + (val) => val.toString() == _enumValueName(field), + ); bool _isWebLibrary(Uri importUri) => importUri.isScheme('dart') && @@ -7308,8 +8083,10 @@ if (_isNull(left) || _isNull(right)) return true; // If the representation of the two types will not induce conversion in // JS then we can use == . - return !_typeRep.equalityMayConvert(left.getStaticType(_staticTypeContext), - right.getStaticType(_staticTypeContext)); + return !_typeRep.equalityMayConvert( + left.getStaticType(_staticTypeContext), + right.getStaticType(_staticTypeContext), + ); } bool _tripleEqIsIdentity(Expression left, Expression right) { @@ -7321,24 +8098,31 @@ /// Returns true if [expr] can be null. bool _isNullable(Expression expr) => _nullableInference.isNullable(expr); - js_ast.Expression _emitJSDoubleEq(List<js_ast.Expression> args, - {bool negated = false}) { + js_ast.Expression _emitJSDoubleEq( + List<js_ast.Expression> args, { + bool negated = false, + }) { var op = negated ? '# != #' : '# == #'; return js.call(op, args); } - js_ast.Expression _emitJSTripleEq(List<js_ast.Expression> args, - {bool negated = false}) { + js_ast.Expression _emitJSTripleEq( + List<js_ast.Expression> args, { + bool negated = false, + }) { var op = negated ? '# !== #' : '# === #'; return js.call(op, args); } - js_ast.Expression _emitCoreIdenticalCall(List<Expression> args, - {bool negated = false}) { + js_ast.Expression _emitCoreIdenticalCall( + List<Expression> args, { + bool negated = false, + }) { if (args.length != 2) { // Shouldn't happen in typechecked code return _runtimeCall( - 'throw(Error("compile error: calls to `identical` require 2 args")'); + 'throw(Error("compile error: calls to `identical` require 2 args")', + ); } var left = args[0]; var right = args[1]; @@ -7350,8 +8134,10 @@ return _emitJSDoubleEq(jsArgs, negated: negated); } var code = negated ? '!#' : '#'; - return js.call(code, - js_ast.Call(_emitTopLevelName(_coreTypes.identicalProcedure), jsArgs)); + return js.call( + code, + js_ast.Call(_emitTopLevelName(_coreTypes.identicalProcedure), jsArgs), + ); } /// Returns true if this [member] is a JS interop member. @@ -7368,16 +8154,15 @@ var shouldProvideRti = !isJSInteropMember(ctor) && _requiresRtiForInstantiation(ctorClass); var rti = shouldProvideRti - ? _emitType(node.constructedType, - emitJSInteropGenericClassTypeParametersAsAny: false) + ? _emitType( + node.constructedType, + emitJSInteropGenericClassTypeParametersAsAny: false, + ) : null; - var result = js_ast.New( - _emitConstructorName(node.constructedType, ctor), - [ - if (rti != null) rti, - ..._emitArgumentList(args, types: false, target: ctor) - ], - ); + var result = js_ast.New(_emitConstructorName(node.constructedType, ctor), [ + if (rti != null) rti, + ..._emitArgumentList(args, types: false, target: ctor), + ]); return node.isConst ? _canonicalizeConstObject(result) : result; } @@ -7443,8 +8228,10 @@ var rti = _requiresRtiForInstantiation(ctorClass) ? _emitType(type, emitJSInteropGenericClassTypeParametersAsAny: false) : null; - var result = js_ast.Call(_emitConstructorName(type, ctor), - [if (rti != null) rti, ..._emitArgumentList(args, types: false)]); + var result = js_ast.Call(_emitConstructorName(type, ctor), [ + if (rti != null) rti, + ..._emitArgumentList(args, types: false), + ]); return node.isConst ? _canonicalizeConstObject(result) : result; } @@ -7453,8 +8240,9 @@ if (isJSAnonymousType(ctorClass)) return _emitObjectLiteral(args, ctor); // JS interop constructor calls do not require an RTI at the call site. return js_ast.New( - _emitConstructorName(_coreTypes.nonNullableRawType(ctorClass), ctor), - _emitArgumentList(args, types: false, target: ctor)); + _emitConstructorName(_coreTypes.nonNullableRawType(ctorClass), ctor), + _emitArgumentList(args, types: false, target: ctor), + ); } InterfaceType _createMapImplType(InterfaceType type, {bool? identity}) { @@ -7489,23 +8277,31 @@ var operand = node.operand; if (operand is EqualsCall) { return _emitEqualityOperator( - operand.left, operand.interfaceTarget, operand.right, - negated: true); + operand.left, + operand.interfaceTarget, + operand.right, + negated: true, + ); } else if (operand is EqualsNull) { - return _emitCoreIdenticalCall([operand.expression, NullLiteral()], - negated: true); + return _emitCoreIdenticalCall([ + operand.expression, + NullLiteral(), + ], negated: true); } else if (operand is StaticInvocation && operand.target == _coreTypes.identicalProcedure) { - return _emitCoreIdenticalCall(operand.arguments.positional, - negated: true); + return _emitCoreIdenticalCall( + operand.arguments.positional, + negated: true, + ); } var jsOperand = _visitTest(operand); if (jsOperand is js_ast.LiteralBool) { // Flipping the value here for `!true` or `!false` allows for simpler // `if (true)` or `if (false)` detection and optimization. - return js_ast.LiteralBool(!jsOperand.value) - .withSourceInformation(jsOperand.sourceInformation) + return js_ast.LiteralBool( + !jsOperand.value, + ).withSourceInformation(jsOperand.sourceInformation) as js_ast.LiteralBool; } @@ -7558,8 +8354,10 @@ continue; } var type = e.getStaticType(_staticTypeContext).extensionTypeErasure; - if (DartTypeEquivalence(_coreTypes, ignoreTopLevelNullability: true) - .areEqual(type, _coreTypes.stringNonNullableRawType) && + if (DartTypeEquivalence( + _coreTypes, + ignoreTopLevelNullability: true, + ).areEqual(type, _coreTypes.stringNonNullableRawType) && !_isNullable(e)) { parts.add(jsExpr); } else if (_shouldCallObjectMemberHelper(e)) { @@ -7611,7 +8409,8 @@ @override js_ast.Expression visitRedirectingFactoryTearOff( - RedirectingFactoryTearOff node) { + RedirectingFactoryTearOff node, + ) { throw UnsupportedError('RedirectingFactory tear off'); } @@ -7647,7 +8446,7 @@ return js.call('#.#(#)', [ _emitType(type), _emitMemberName(js_ast.FixedNames.rtiIsField, memberClass: _rtiClass), - lhs + lhs, ]); } @@ -7656,13 +8455,20 @@ var fromExpr = node.operand; var jsFrom = _visitExpression(fromExpr); if (node.isUnchecked) return jsFrom; - return _emitCast(jsFrom, node.type, - fromStaticType: fromExpr.getStaticType(_staticTypeContext), - isTypeError: node.isTypeError); + return _emitCast( + jsFrom, + node.type, + fromStaticType: fromExpr.getStaticType(_staticTypeContext), + isTypeError: node.isTypeError, + ); } - js_ast.Expression _emitCast(js_ast.Expression value, DartType toType, - {DartType? fromStaticType, bool isTypeError = false}) { + js_ast.Expression _emitCast( + js_ast.Expression value, + DartType toType, { + DartType? fromStaticType, + bool isTypeError = false, + }) { toType = toType.extensionTypeErasure; if (_types.isTop(toType)) return value; if (fromStaticType != null) { @@ -7686,13 +8492,18 @@ // if (!isTypeError && _types.isSubtypeOf( - fromStaticType, toType, SubtypeCheckMode.withNullabilities)) { + fromStaticType, + toType, + SubtypeCheckMode.withNullabilities, + )) { return value; } if (!isTypeError && _mustBeNonNullable(toType) && - DartTypeEquivalence(_coreTypes, ignoreTopLevelNullability: true) - .areEqual(fromStaticType, toType)) { + DartTypeEquivalence( + _coreTypes, + ignoreTopLevelNullability: true, + ).areEqual(fromStaticType, toType)) { // If the underlying type is the same, we only need a null check. return _runtimeCall('nullCast(#, #)', [value, _emitType(toType)]); } @@ -7723,7 +8534,7 @@ return js.call('#.#(#)', [ _emitType(toType), _emitMemberName(js_ast.FixedNames.rtiAsField, memberClass: _rtiClass), - value + value, ]); } @@ -7766,8 +8577,10 @@ // If the type is a type literal expression in Dart code, wrap the raw // runtime type in a "Type" instance. - return js.call( - '#.createRuntimeType(#)', [_emitLibraryName(_rtiLibrary), typeRep]); + return js.call('#.createRuntimeType(#)', [ + _emitLibraryName(_rtiLibrary), + typeRep, + ]); } @override @@ -7790,46 +8603,61 @@ } js_ast.Expression _emitList( - DartType itemType, List<js_ast.Expression> items) { + DartType itemType, + List<js_ast.Expression> items, + ) { var list = js_ast.ArrayInitializer(items); // List's type parameter is default-initialized to dynamic in our runtime. if (itemType == const DynamicType()) return list; // Call `new JSArray<E>.of(list)` - var type = - InterfaceType(_jsArrayClass, Nullability.nonNullable, [itemType]); + var type = InterfaceType(_jsArrayClass, Nullability.nonNullable, [ + itemType, + ]); var arrayClass = _emitClassRef(type); var arrayRti = _emitType(type); return js.call('#.of(#, #)', [arrayClass, arrayRti, list]); } js_ast.Expression _emitConstList( - DartType elementType, List<js_ast.Expression> elements) { - return _runtimeCall( - 'constList(#, [#])', [_emitType(elementType), elements]); + DartType elementType, + List<js_ast.Expression> elements, + ) { + return _runtimeCall('constList(#, [#])', [ + _emitType(elementType), + elements, + ]); } @override js_ast.Expression visitSetLiteral(SetLiteral node) { // TODO(markzipan): remove const check when we use front-end const eval if (!node.isConst) { - var type = InterfaceType( - _linkedHashSetClass, Nullability.nonNullable, [node.typeArgument]); + var type = InterfaceType(_linkedHashSetClass, Nullability.nonNullable, [ + node.typeArgument, + ]); var setClass = _emitClassRef(type); var rti = _emitType(type); if (node.expressions.isEmpty) { return js.call('#.new(#)', [setClass, rti]); } - return js.call('#.from(#, [#])', - [setClass, rti, _visitExpressionList(node.expressions)]); + return js.call('#.from(#, [#])', [ + setClass, + rti, + _visitExpressionList(node.expressions), + ]); } return _emitConstSet( - node.typeArgument, _visitExpressionList(node.expressions)); + node.typeArgument, + _visitExpressionList(node.expressions), + ); } js_ast.Expression _emitConstSet( - DartType elementType, List<js_ast.Expression> elements) { + DartType elementType, + List<js_ast.Expression> elements, + ) { return _runtimeCall('constSet(#, [#])', [_emitType(elementType), elements]); } @@ -7857,16 +8685,24 @@ } js_ast.Expression _emitConstMap( - DartType keyType, DartType valueType, List<js_ast.Expression> entries) { - return _runtimeCall('constMap(#, #, [#])', - [_emitType(keyType), _emitType(valueType), entries]); + DartType keyType, + DartType valueType, + List<js_ast.Expression> entries, + ) { + return _runtimeCall('constMap(#, #, [#])', [ + _emitType(keyType), + _emitType(valueType), + entries, + ]); } /// Returns the key used for shape lookup at runtime. /// /// See `shapes` in dart:_runtime (records.dart) for a description. String _recordShapeKey( - int positionalElementCount, Iterable<String> namedElementNames) { + int positionalElementCount, + Iterable<String> namedElementNames, + ) { var elementCount = positionalElementCount + namedElementNames.length; return '$elementCount;${namedElementNames.join(',')}'; } @@ -7883,7 +8719,7 @@ [ for (var positional in node.positional) _visitExpression(positional), for (var named in node.named) _visitExpression(named.value), - ] + ], ]); return shapeExpr; } @@ -7898,8 +8734,11 @@ // checked at runtime to ensure soundness. var expectedType = _emitType(type); var asyncLibrary = _emitLibraryName(_coreTypes.asyncLibrary); - expression = js.call('#.awaitWithTypeCheck(#, #)', - [asyncLibrary, expectedType, expression]); + expression = js.call('#.awaitWithTypeCheck(#, #)', [ + asyncLibrary, + expectedType, + expression, + ]); } return js_ast.Await(expression); } @@ -7912,7 +8751,9 @@ _inFunctionExpression = savedInFunctionExpression; if (!_reifyFunctionType(node.function)) return fn; return _emitFunctionTagged( - fn, node.getStaticType(_staticTypeContext) as FunctionType); + fn, + node.getStaticType(_staticTypeContext) as FunctionType, + ); } js_ast.ArrowFun _emitArrowFunction(FunctionExpression node) { @@ -7979,12 +8820,13 @@ final isAsyncIife = asyncAnalysis.hasAwaitOrYield.contains(body); if (isAsyncIife) { final transformedFunction = _rewriteAsyncFunction( - js_ast.Fun([temp], js_ast.Block([js_ast.Return(body)])), - AsyncMarker.Async, - null, - node.getStaticType(_staticTypeContext), - functionBody: _toSourceLocation(node.fileOffset), - functionEnd: _toSourceLocation(node.fileOffset)); + js_ast.Fun([temp], js_ast.Block([js_ast.Return(body)])), + AsyncMarker.Async, + null, + node.getStaticType(_staticTypeContext), + functionBody: _toSourceLocation(node.fileOffset), + functionEnd: _toSourceLocation(node.fileOffset), + ); arrowFunction = js_ast.ArrowFun([temp], transformedFunction.body); } final call = js_ast.Call(arrowFunction, [init]); @@ -8005,19 +8847,21 @@ var arrowFunction = js_ast.ArrowFun(const [], statementBlock); final asyncAnalysis = PreTranslationAnalysis((node) { throw UnsupportedError( - 'Unknown node in block expression: $node (${node.runtimeType}, ' - '${node.sourceInformation})'); + 'Unknown node in block expression: $node (${node.runtimeType}, ' + '${node.sourceInformation})', + ); }, arrowFunction) ..analyze(); final isAsyncIife = asyncAnalysis.hasAwaitOrYield.contains(statementBlock); if (isAsyncIife) { final transformedFunction = _rewriteAsyncFunction( - js_ast.Fun(const [], statementBlock), - AsyncMarker.Async, - null, - node.getStaticType(_staticTypeContext), - functionBody: _toSourceLocation(node.fileOffset), - functionEnd: _toSourceLocation(node.fileOffset)); + js_ast.Fun(const [], statementBlock), + AsyncMarker.Async, + null, + node.getStaticType(_staticTypeContext), + functionBody: _toSourceLocation(node.fileOffset), + functionEnd: _toSourceLocation(node.fileOffset), + ); arrowFunction = js_ast.ArrowFun(const [], transformedFunction.body); } final call = js_ast.Call(arrowFunction, const []); @@ -8028,7 +8872,7 @@ js_ast.Expression visitInstantiation(Instantiation node) { return _runtimeCall('gbind(#, #)', [ _visitExpression(node.expression), - node.typeArguments.map(_emitType).toList() + node.typeArguments.map(_emitType).toList(), ]); } @@ -8038,7 +8882,8 @@ js.string(node.import.enclosingLibrary.importUri.toString()), js.string(node.import.name!), js.string( - _libraryToModule(node.import.targetLibrary, throwIfNotFound: false)) + _libraryToModule(node.import.targetLibrary, throwIfNotFound: false), + ), ]); // TODO(jmesserly): DDC loads all libraries eagerly. @@ -8049,7 +8894,7 @@ js_ast.Expression visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) => _runtimeCall('checkDeferredIsLoaded(#, #)', [ js.string(node.import.enclosingLibrary.importUri.toString()), - js.string(node.import.name!) + js.string(node.import.name!), ]); bool _reifyFunctionType(FunctionNode f) { @@ -8118,7 +8963,7 @@ if (node.target.isExternal && !isSdk) { return _runtimeCall('tearoffInterop(#, #)', [ _emitStaticTarget(node.target), - js.boolean(_isNullCheckableJsInterop(node.target)) + js.boolean(_isNullCheckableJsInterop(node.target)), ]); } } @@ -8147,16 +8992,20 @@ _constTableCache[constAliasString] = js.call('void 0'); var constAliasAccessor = _constTableCache.access(constAliasString); - var constAccessor = js.call( - '# || #.#', [constAliasAccessor, _constTable, constAliasProperty]); + var constAccessor = js.call('# || #.#', [ + constAliasAccessor, + _constTable, + constAliasProperty, + ]); _constAliasCache[node] = constAccessor; var constJs = super.visitConstant(node); var func = js_ast.Fun( - [], - js_ast.Block([ - js.statement('return # = #;', [constAliasAccessor, constJs]) - ])); + [], + js_ast.Block([ + js.statement('return # = #;', [constAliasAccessor, constJs]), + ]), + ); var accessor = js_ast.Method(constAliasProperty, func, isGetter: true); _constLazyAccessors.add(accessor); return constAccessor; @@ -8223,11 +9072,15 @@ @override js_ast.Expression visitListConstant(ListConstant node) => _emitConstList( - node.typeArgument, node.entries.map(visitConstant).toList()); + node.typeArgument, + node.entries.map(visitConstant).toList(), + ); @override js_ast.Expression visitSetConstant(SetConstant node) => _emitConstSet( - node.typeArgument, node.entries.map(visitConstant).toList()); + node.typeArgument, + node.entries.map(visitConstant).toList(), + ); @override js_ast.Expression visitRecordConstant(RecordConstant node) { @@ -8241,15 +9094,17 @@ names.isEmpty ? js.call('void 0') : js.stringArray(names), [ ...node.positional.map(visitConstant), - ...node.named.values.map(visitConstant) - ] + ...node.named.values.map(visitConstant), + ], ]); } js_ast.Expression visitEnum(InstanceConstant node) { var type = node.getType(_staticTypeContext); - assert(type.nullability == Nullability.nonNullable, - 'An instance constant should only ever have a non-nullable type.'); + assert( + type.nullability == Nullability.nonNullable, + 'An instance constant should only ever have a non-nullable type.', + ); var classRef = _emitClassRef(type as InterfaceType); var prototype = js.call('#.prototype', [classRef]); var enumAccessor = _emitTopLevelName(node.classNode); @@ -8262,7 +9117,9 @@ if (type.typeArguments.isNotEmpty) { // Generic interface type instances require a type information tag. var property = js_ast.Property( - _propertyName(js_ast.FixedNames.rtiName), _emitType(type)); + _propertyName(js_ast.FixedNames.rtiName), + _emitType(type), + ); constantProperties.add(property); } node.fieldValues.forEach((k, v) { @@ -8274,35 +9131,51 @@ // We transform the 'index' field of Enum fields into a special // getter so that their indices are consistent across hot reloads. var value = js.call('#.values.indexOf(this)', enumAccessor); - var jsMember = _getSymbol(_emitClassPrivateNameSymbol( + var jsMember = _getSymbol( + _emitClassPrivateNameSymbol( memberClass.enclosingLibrary, getLocalClassName(memberClass), - member)); - additionalProperties.add(js_ast.Method( - jsMember, js.fun('function() { return #; }', [value]), - isGetter: true)); + member, + ), + ); + additionalProperties.add( + js_ast.Method( + jsMember, + js.fun('function() { return #; }', [value]), + isGetter: true, + ), + ); } else { - var jsMember = _getSymbol(_emitClassPrivateNameSymbol( + var jsMember = _getSymbol( + _emitClassPrivateNameSymbol( memberClass.enclosingLibrary, getLocalClassName(memberClass), - member)); + member, + ), + ); constantProperties.add(js_ast.Property(jsMember, constant)); } } else { - additionalProperties.add(js_ast.Property( - _emitMemberName(member.name.text, member: member), constant)); + additionalProperties.add( + js_ast.Property( + _emitMemberName(member.name.text, member: member), + constant, + ), + ); } }); var canonicalizedEnum = _canonicalizeConstObject( - _emitJSObjectSetPrototypeOf( - js_ast.ObjectInitializer(constantProperties, multiline: true), - prototype, - fullyQualifiedName: false)); + _emitJSObjectSetPrototypeOf( + js_ast.ObjectInitializer(constantProperties, multiline: true), + prototype, + fullyQualifiedName: false, + ), + ); var enumExtension = _runtimeStatement('extendEnum(#, #)', [ canonicalizedEnum, - js_ast.ObjectInitializer(additionalProperties, multiline: true) + js_ast.ObjectInitializer(additionalProperties, multiline: true), ]); _enumExtensions.add(enumExtension); @@ -8313,8 +9186,9 @@ js_ast.Expression visitInstanceConstant(InstanceConstant node) { var savedTypeEnvironment = _currentTypeEnvironment; if (node.classNode.typeParameters.isNotEmpty) { - _currentTypeEnvironment = - ClassTypeEnvironment(node.classNode.typeParameters); + _currentTypeEnvironment = ClassTypeEnvironment( + node.classNode.typeParameters, + ); } if (node.classNode.isEnum) { @@ -8327,27 +9201,40 @@ var constant = visitConstant(entry.value); var member = entry.key.asField; var cls = member.enclosingClass!; - var symbol = _getSymbol(_emitClassPrivateNameSymbol( - cls.enclosingLibrary, getLocalClassName(cls), member)); + var symbol = _getSymbol( + _emitClassPrivateNameSymbol( + cls.enclosingLibrary, + getLocalClassName(cls), + member, + ), + ); return js_ast.Property(symbol, constant); } var type = node.getType(_staticTypeContext); - assert(type.nullability == Nullability.nonNullable, - 'An instance constant should only ever have a non-nullable type.'); + assert( + type.nullability == Nullability.nonNullable, + 'An instance constant should only ever have a non-nullable type.', + ); var classRef = _emitClassRef(type as InterfaceType); var prototype = js.call('#.prototype', [classRef]); var properties = [ if (type.typeArguments.isNotEmpty) // Generic interface type instances require a type information tag. js_ast.Property( - _propertyName(js_ast.FixedNames.rtiName), _emitType(type)), + _propertyName(js_ast.FixedNames.rtiName), + _emitType(type), + ), for (var e in node.fieldValues.entries.toList().reversed) entryToProperty(e), ]; - var constant = _canonicalizeConstObject(_emitJSObjectSetPrototypeOf( - js_ast.ObjectInitializer(properties, multiline: true), prototype, - fullyQualifiedName: false)); + var constant = _canonicalizeConstObject( + _emitJSObjectSetPrototypeOf( + js_ast.ObjectInitializer(properties, multiline: true), + prototype, + fullyQualifiedName: false, + ), + ); _currentTypeEnvironment = savedTypeEnvironment; return constant; } @@ -8358,8 +9245,11 @@ /// This is now required for fields of constant objects that may be overridden /// within the same library. js_ast.ScopedId _emitClassPrivateNameSymbol( - Library library, String className, Member member, - [js_ast.ScopedId? id]) { + Library library, + String className, + Member member, [ + js_ast.ScopedId? id, + ]) { var name = '$className.${member.name.text}'; // Wrap the name as a symbol here so it matches what you would find at // runtime when you get all properties and symbols from an instance. @@ -8378,10 +9268,12 @@ @override js_ast.Expression visitInstantiationConstant(InstantiationConstant node) => - _canonicalizeConstObject(_runtimeCall('gbind(#, #)', [ - visitConstant(node.tearOffConstant), - node.types.map(_emitType).toList() - ])); + _canonicalizeConstObject( + _runtimeCall('gbind(#, #)', [ + visitConstant(node.tearOffConstant), + node.types.map(_emitType).toList(), + ]), + ); @override js_ast.Expression visitUnevaluatedConstant(UnevaluatedConstant node) => @@ -8400,8 +9292,10 @@ // This is here to preserve the existing behavior for the non-static // JavaScript interop (including some failing cases) but could potentially // be cleaned up as a breaking change. - return _runtimeCall( - 'dload$_replSuffix(#, #)', [jsReceiver, js.string('call')]); + return _runtimeCall('dload$_replSuffix(#, #)', [ + jsReceiver, + js.string('call'), + ]); } // Otherwise, tearoff of `call` on a function type is a no-op. return jsReceiver; @@ -8430,7 +9324,8 @@ @override js_ast.Statement visitPatternVariableDeclaration( - PatternVariableDeclaration node) { + PatternVariableDeclaration node, + ) { // This node is internal to the front end and removed by the constant // evaluator. throw UnsupportedError('ProgramCompiler.visitPatternVariableDeclaration'); @@ -8446,13 +9341,15 @@ @override js_ast.Expression visitAuxiliaryExpression(AuxiliaryExpression node) { throw UnsupportedError( - 'Unsupported auxiliary expression $node (${node.runtimeType}).'); + 'Unsupported auxiliary expression $node (${node.runtimeType}).', + ); } @override js_ast.Statement visitAuxiliaryStatement(AuxiliaryStatement node) { throw UnsupportedError( - 'Unsupported auxiliary statement $node (${node.runtimeType}).'); + 'Unsupported auxiliary statement $node (${node.runtimeType}).', + ); } void _setEmitIfIncrementalLibrary(Library library) { @@ -8479,12 +9376,17 @@ /// implement special handling of the user-defined `[]=` and `==` methods. /// /// See also [_exitFunction] and [_emitReturnStatement]. - void _enterFunction(String? name, List<js_ast.Parameter> formals, - bool Function() isLastParamMutated) { + void _enterFunction( + String? name, + List<js_ast.Parameter> formals, + bool Function() isLastParamMutated, + ) { if (name == '[]=') { - _operatorSetResultStack.add(isLastParamMutated() - ? js_ast.ScopedId((formals.last as js_ast.Identifier).name) - : formals.last as js_ast.Identifier); + _operatorSetResultStack.add( + isLastParamMutated() + ? js_ast.ScopedId((formals.last as js_ast.Identifier).name) + : formals.last as js_ast.Identifier, + ); } else { _operatorSetResultStack.add(null); } @@ -8493,7 +9395,9 @@ /// Called when finished emitting methods/functions, and must correspond to a /// previous [_enterFunction] call. js_ast.Block _exitFunction( - List<js_ast.Parameter> formals, js_ast.Block code) { + List<js_ast.Parameter> formals, + js_ast.Block code, + ) { var setOperatorResult = _operatorSetResultStack.removeLast(); if (setOperatorResult != null) { // []= methods need to return the value. We could also address this at @@ -8507,8 +9411,11 @@ // If the value parameter was mutated, then we use a temporary // variable to track the initial value formals.last = setOperatorResult; - code = js - .block('{ let # = #; #; }', [valueParam, setOperatorResult, code]); + code = js.block('{ let # = #; #; }', [ + valueParam, + setOperatorResult, + code, + ]); } } return code; @@ -8538,8 +9445,10 @@ /// dart.asInt(<expr>) /// js_ast.Expression _runtimeCall(String code, [List<Object>? args]) { - return js - .call('#.$code', <Object>[_emitLibraryName(_runtimeLibrary), ...?args]); + return js.call('#.$code', <Object>[ + _emitLibraryName(_runtimeLibrary), + ...?args, + ]); } /// Calls [_runtimeCall] and uses `toStatement()` to convert the resulting @@ -8560,8 +9469,11 @@ /// define new symbols and to reference existing ones. If it's called /// multiple times with same [library] and [name], we'll allocate redundant /// top-level variables (see callers to this method). - js_ast.ScopedId _emitPrivateNameSymbol(Library library, String name, - [js_ast.ScopedId? id]) { + js_ast.ScopedId _emitPrivateNameSymbol( + Library library, + String name, [ + js_ast.ScopedId? id, + ]) { /// Initializes the JS `Symbol` for the private member [name] in [library]. /// /// If the library is in the current JS module ([_libraries] contains it), @@ -8580,17 +9492,24 @@ idName = idName.replaceAll(js_ast.invalidCharInIdentifier, '_'); var identifier = id ?? js_ast.ScopedId(idName); _addSymbol( - identifier, - _runtimeCall('privateName(#, #)', - [js.string('${library.importUri}'), js.string(name)])); + identifier, + _runtimeCall('privateName(#, #)', [ + js.string('${library.importUri}'), + js.string(name), + ]), + ); if (!_containerizeSymbols) { // TODO(vsm): Change back to `const`. // See https://github.com/dart-lang/sdk/issues/40380. - _moduleItems.add(js.statement('var # = #', [ - identifier, - _runtimeCall('privateName(#, #)', - [js.string('${library.importUri}'), js.string(name)]) - ])); + _moduleItems.add( + js.statement('var # = #', [ + identifier, + _runtimeCall('privateName(#, #)', [ + js.string('${library.importUri}'), + js.string(name), + ]), + ]), + ); } return identifier; } @@ -8600,20 +9519,26 @@ _setEmitIfIncrementalLibrary(library); _setEmitIfIncremental( - _libraryToModule(_coreLibrary), _runtimeLibraryId.name); + _libraryToModule(_coreLibrary), + _runtimeLibraryId.name, + ); _symbolContainer.setEmitIfIncremental(symbolId); return symbolId; } - /// Emits an expression to set the property [nameExpr] on the class [className], - /// with [value]. + /// Emits an expression to set the property [nameExpr] on the class + /// [className], with [value]. /// /// This will use `className.name = value` if possible, otherwise it will use /// `dart.defineValue(className, name, value)`. This is required when /// `FunctionNode.prototype` already defines a getters with the same name. - js_ast.Expression _defineValueOnClass(Class c, js_ast.Expression className, - js_ast.Expression nameExpr, js_ast.Expression value) { + js_ast.Expression _defineValueOnClass( + Class c, + js_ast.Expression className, + js_ast.Expression nameExpr, + js_ast.Expression value, + ) { var args = [className, nameExpr, value]; if (nameExpr is js_ast.LiteralString) { var name = nameExpr.valueWithoutQuotes; @@ -8635,16 +9560,19 @@ var name = js.escapedString(symbolName, "'"); js_ast.Expression result; if (last.startsWith('_')) { - var nativeSymbolAccessor = - _getSymbol(_emitPrivateNameSymbol(_currentLibrary!, last)); + var nativeSymbolAccessor = _getSymbol( + _emitPrivateNameSymbol(_currentLibrary!, last), + ); result = js.call('new #.new(#, #)', [ _emitConstructorAccess(_privateSymbolType), name, - nativeSymbolAccessor + nativeSymbolAccessor, ]); } else { - result = js.call( - 'new #.new(#)', [_emitConstructorAccess(_internalSymbolType), name]); + result = js.call('new #.new(#)', [ + _emitConstructorAccess(_internalSymbolType), + name, + ]); } return _canonicalizeConstObject(result); } @@ -8674,8 +9602,9 @@ // Don't allow these to be renamed when we're building the SDK. // There is JS code in dart:* that depends on their names. _runtimeLibraryId = js_ast.Identifier('dart'); - _extensionSymbolsLibraryId = - js_ast.Identifier(_extensionSymbolHolderName); + _extensionSymbolsLibraryId = js_ast.Identifier( + _extensionSymbolHolderName, + ); } else { // Otherwise allow these to be renamed so users can write them. _runtimeLibraryId = js_ast.ScopedId('dart'); @@ -8704,7 +9633,9 @@ // To bootstrap the SDK, this needs to be emitted before other code. var privateNamesId = _emitScopedId('privateNames'); items.add(js.statement('const # = new Map()', privateNamesId)); - items.add(_runtimeStatement(r''' + items.add( + _runtimeStatement( + r''' privateName = function privateName(libraryUri, name) { let names = #.get(libraryUri); if (names == null) #.set(libraryUri, names = new Map()); @@ -8712,7 +9643,10 @@ if (symbol == null) names.set(name, symbol = Symbol(name)); return symbol; } - ''', [privateNamesId, privateNamesId])); + ''', + [privateNamesId, privateNamesId], + ), + ); } return items; @@ -8745,9 +9679,9 @@ // Generate import directives. // - // Our import variables are temps and can get renamed. Since our renaming - // is integrated into js_ast, it is aware of this possibility and will - // generate an "as" if needed. For example: + // Our import variables are temps and can get renamed. Since our + // renaming is integrated into js_ast, it is aware of this possibility + // and will generate an "as" if needed. For example: // // import {foo} from 'foo'; // if no rename needed // import {foo as foo$} from 'foo'; // if rename was needed @@ -8758,35 +9692,51 @@ var alias = _jsLibraryAlias(library); if (alias != null) { var aliasId = js_ast.ScopedId(alias); - items.add(js_ast.ImportDeclaration( + items.add( + js_ast.ImportDeclaration( from: js.string('${library.importUri}'), namedImports: [ - js_ast.NameSpecifier(aliasId, asName: _imports[library]) - ])); + js_ast.NameSpecifier(aliasId, asName: _imports[library]), + ], + ), + ); } else { - items.add(js_ast.ImportDeclaration( + items.add( + js_ast.ImportDeclaration( from: js.string('${library.importUri}'), - namedImports: [js_ast.NameSpecifier(_imports[library])])); + namedImports: [js_ast.NameSpecifier(_imports[library])], + ), + ); } } } } }); - items.add(js_ast.ImportDeclaration( + items.add( + js_ast.ImportDeclaration( from: js.string(_extensionSymbolHolderName), - namedImports: [js_ast.NameSpecifier(_extensionSymbolsLibraryId)])); + namedImports: [js_ast.NameSpecifier(_extensionSymbolsLibraryId)], + ), + ); } /// Emits extension methods into [items]. - void _emitExtensionSymbols(List<js_ast.ModuleItem> items, - {bool forceExtensionSymbols = false}) { + void _emitExtensionSymbols( + List<js_ast.ModuleItem> items, { + bool forceExtensionSymbols = false, + }) { // Initialize extension symbols _extensionSymbols.forEach((name, id) { js_ast.Expression value = js_ast.PropertyAccess( - _extensionSymbolsLibraryId, _propertyName(name)); + _extensionSymbolsLibraryId, + _propertyName(name), + ); if (forceExtensionSymbols) { - value = js.call('# || (# = Symbol(#))', - [value, value, js.string('$_extensionSymbolHolderName.$name')]); + value = js.call('# || (# = Symbol(#))', [ + value, + value, + js.string('$_extensionSymbolHolderName.$name'), + ]); } // Emit hoisted extension symbols that are marked as noEmit in regular as // well as incremental mode (if needed) since they are going to be @@ -8802,7 +9752,9 @@ } if (_symbolContainer.incrementalModuleItems.contains(id)) { _setEmitIfIncremental( - _libraryToModule(_coreLibrary), _extensionSymbolsLibraryId.name); + _libraryToModule(_coreLibrary), + _extensionSymbolsLibraryId.name, + ); } _symbolContainer[id] = value; }); @@ -8851,15 +9803,20 @@ } }); - items.add(js_ast.ImportDeclaration( + items.add( + js_ast.ImportDeclaration( namedImports: exports, - from: js.string(current.importUri.toString(), "'"))); + from: js.string(current.importUri.toString(), "'"), + ), + ); } } /// Emits imports and extension methods into [items]. - void _emitImportsAndExtensionSymbols(List<js_ast.ModuleItem> items, - {bool forceExtensionSymbols = false}) { + void _emitImportsAndExtensionSymbols( + List<js_ast.ModuleItem> items, { + bool forceExtensionSymbols = false, + }) { _emitImports(items); _emitExtensionSymbols(items, forceExtensionSymbols: forceExtensionSymbols); } @@ -8899,11 +9856,15 @@ /// /// Note, this function mutates the items list and returns it as the `body` /// field of the result. - js_ast.Program _finishLibrary(List<js_ast.ModuleItem> items, - String libraryName, js_ast.Identifier libraryId) { + js_ast.Program _finishLibrary( + List<js_ast.ModuleItem> items, + String libraryName, + js_ast.Identifier libraryId, + ) { // TODO(jmesserly): there's probably further consolidation we can do // between DDC's two backends, by moving more code into this method, as the - // code between `_startLibrary` and `_finishLibrary` is very similar in both. + // code between `_startLibrary` and `_finishLibrary` is very similar in + // both. // Emit all top-level JS symbol containers. items.addAll(_symbolContainer.emit()); @@ -8912,8 +9873,11 @@ // Expose the entrypoint of the dynamic module under a reserved name. // TODO(sigmund): this could use a reserved symbol from dartx. var name = _emitTopLevelName(_dynamicEntrypoint!); - _moduleItems.add(js_ast.ExportDeclaration( - js('var __dynamic_module_entrypoint__ = #', [name]))); + _moduleItems.add( + js_ast.ExportDeclaration( + js('var __dynamic_module_entrypoint__ = #', [name]), + ), + ); } // Add the library's code (produced by visiting compilation units, above) @@ -8928,7 +9892,9 @@ /// /// This will not flatten blocks that are marked as being scopes. void _copyAndFlattenBlocks( - List<js_ast.ModuleItem> result, Iterable<js_ast.ModuleItem> items) { + List<js_ast.ModuleItem> result, + Iterable<js_ast.ModuleItem> items, + ) { for (var item in items) { if (item is js_ast.Block && !item.isScope) { _copyAndFlattenBlocks(result, item.statements); @@ -8947,7 +9913,8 @@ js_ast.ScopedId _getExtensionSymbolInternal(String name) { if (!_extensionSymbols.containsKey(name)) { var id = js_ast.ScopedId( - '\$${js_ast.friendlyNameForDartOperator[name] ?? name}'); + '\$${js_ast.friendlyNameForDartOperator[name] ?? name}', + ); _extensionSymbols[name] = id; _addSymbol(id, id); } @@ -8976,13 +9943,15 @@ /// Matches against the `dart:js_util` `_callMethodUnchecked` and /// `_callMethodUncheckedTrustType` variants with 0 to 4 arguments. - static final RegExp _callMethodUncheckedRegex = - RegExp(r'^\_callMethodUnchecked(TrustType)?[0-4]'); + static final RegExp _callMethodUncheckedRegex = RegExp( + r'^\_callMethodUnchecked(TrustType)?[0-4]', + ); /// Matches against the `dart:js_util` `_callConstructorUnchecked` and /// `_callConstructorUncheckedTrustType` variants with 0 to 4 arguments. - static final RegExp _callConstructorUncheckedRegex = - RegExp(r'^\_callConstructorUnchecked[0-4]'); + static final RegExp _callConstructorUncheckedRegex = RegExp( + r'^\_callConstructorUnchecked[0-4]', + ); } bool _isInlineJSFunction(Statement? body) {
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart index 072d194..c11c006 100644 --- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
@@ -18,11 +18,18 @@ import 'compiler.dart' show Compiler; DiagnosticMessage _createInternalError(Uri uri, int line, int col, String msg) { - return Message(Code<String>('Expression Compiler Internal error'), - problemMessage: msg) + return Message( + Code<String>('Expression Compiler Internal error'), + problemMessage: msg, + ) .withLocation(uri, 0, 0) - .withFormatting(PlainAndColorizedString.plainOnly('Internal error: $msg'), - line, col, Severity.internalProblem, []); + .withFormatting( + PlainAndColorizedString.plainOnly('Internal error: $msg'), + line, + col, + Severity.internalProblem, + [], + ); } class ExpressionCompiler { @@ -51,8 +58,8 @@ this._compiler, this._kernel2jsCompiler, this._component, - ) : onDiagnostic = _options.onDiagnostic!, - _context = _compiler.context; + ) : onDiagnostic = _options.onDiagnostic!, + _context = _compiler.context; /// Compiles [expression] in library [libraryUri] and file [scriptUri] /// at [line]:[column] to JavaScript in [moduleName]. @@ -76,19 +83,24 @@ /// or another variable name, for example /// { 'x': '1', 'y': 'y', 'o': 'null' } Future<String?> compileExpressionToJs( - String libraryUri, - String? scriptUri, - int line, - int column, - Map<String, String> jsScope, - String expression) async { + String libraryUri, + String? scriptUri, + int line, + int column, + Map<String, String> jsScope, + String expression, + ) async { try { // 1. find dart scope where debugger is paused _log('Compiling expression \n$expression'); - var dartScope = _findScopeAt(Uri.parse(libraryUri), - scriptUri == null ? null : Uri.parse(scriptUri), line, column); + var dartScope = _findScopeAt( + Uri.parse(libraryUri), + scriptUri == null ? null : Uri.parse(scriptUri), + line, + column, + ); if (dartScope == null) { _log('Scope not found at $libraryUri:$line:$column'); return null; @@ -112,8 +124,9 @@ if (isLateLoweredLocalName(name)) name, ]; for (var localName in dartLateLocals) { - dartScope.definitions[extractLocalName(localName)] = - dartScope.definitions.remove(localName)!; + dartScope.definitions[extractLocalName(localName)] = dartScope + .definitions + .remove(localName)!; } // Create a mapping from Dart variable names in scope to the corresponding @@ -147,7 +160,7 @@ // Get the available async scopes. final asyncScopeRegexp = RegExp(r'^asyncScope(\$[0-9]*)?$'); final asyncScopes = [ - ...jsNames.where((e) => asyncScopeRegexp.hasMatch(e)) + ...jsNames.where((e) => asyncScopeRegexp.hasMatch(e)), ]; for (final dartName in dartNames) { @@ -159,8 +172,9 @@ } // Any name containing a '$' symbol will have that symbol expanded to // '$36' in JS. We do a similar expansion here to normalize the names. - final jsNamePrefix = - js_ast.toJSIdentifier(dartName).replaceAll('\$', '\\\$'); + final jsNamePrefix = js_ast + .toJSIdentifier(dartName) + .replaceAll('\$', '\\\$'); final regexp = RegExp(r'^' + jsNamePrefix + r'(\$[0-9]*)?$'); for (var i = 0; i < jsNames.length; i++) { final jsName = jsNames[i]; @@ -219,30 +233,36 @@ // this case return a special sentinel value that we can detect and // throw on. final defaultValue = dartNameToJsValue[dartName] ?? 'sentinel'; - dartNameToJsValue[dartName] = asyncScopes.fold(defaultValue, - (p, e) => '"$dartName" in $e ? $e["$dartName"] : ($p)'); + dartNameToJsValue[dartName] = asyncScopes.fold( + defaultValue, + (p, e) => '"$dartName" in $e ? $e["$dartName"] : ($p)', + ); } } - dartScope.definitions.removeWhere((variable, type) => - // Remove undefined js variables (this allows us to get a reference - // error from chrome on evaluation). - !dartNameToJsValue.containsKey(variable) || - // Remove wildcard method arguments which are lowered to have Dart - // names that are invalid for Dart compilations. - // Wildcard local variables are not appearing here at this time. - isWildcardLoweredFormalParameter(variable)); + dartScope.definitions.removeWhere( + (variable, type) => + // Remove undefined js variables (this allows us to get a reference + // error from chrome on evaluation). + !dartNameToJsValue.containsKey(variable) || + // Remove wildcard method arguments which are lowered to have Dart + // names that are invalid for Dart compilations. + // Wildcard local variables are not appearing here at this time. + isWildcardLoweredFormalParameter(variable), + ); // Wildcard type parameters already matched by this existing test. - dartScope.typeParameters - .removeWhere((parameter) => !jsScope.containsKey(parameter.name)); + dartScope.typeParameters.removeWhere( + (parameter) => !jsScope.containsKey(parameter.name), + ); // map from values from the stack when available (this allows to evaluate // captured variables optimized away in chrome) var localJsScope = [ ...dartScope.typeParameters.map((parameter) => jsScope[parameter.name]), - ...dartScope.definitions.keys - .map((variable) => dartNameToJsValue[variable]) + ...dartScope.definitions.keys.map( + (variable) => dartNameToJsValue[variable], + ), ]; _log('Performed scope substitutions for expression'); @@ -288,23 +308,40 @@ return callExpression; } catch (e, s) { onDiagnostic( - _createInternalError(Uri.parse(libraryUri), line, column, '$e:$s')); + _createInternalError(Uri.parse(libraryUri), line, column, '$e:$s'), + ); return null; } } DartScope? _findScopeAt( - Uri libraryUri, Uri? scriptFileUri, int line, int column) { + Uri libraryUri, + Uri? scriptFileUri, + int line, + int column, + ) { if (line < 0) { - onDiagnostic(_createInternalError( - libraryUri, line, column, 'Invalid source location')); + onDiagnostic( + _createInternalError( + libraryUri, + line, + column, + 'Invalid source location', + ), + ); return null; } var library = _getLibrary(libraryUri); if (library == null) { - onDiagnostic(_createInternalError( - libraryUri, line, column, 'Dart library not found for location')); + onDiagnostic( + _createInternalError( + libraryUri, + line, + column, + 'Dart library not found for location', + ), + ); return null; } @@ -312,8 +349,11 @@ // but for now use the old mechanism when no script is provided. if (scriptFileUri != null) { final offset = _component.getOffset(library.fileUri, line, column); - final scope2 = - DartScopeBuilder2.findScopeFromOffset(library, scriptFileUri, offset); + final scope2 = DartScopeBuilder2.findScopeFromOffset( + library, + scriptFileUri, + offset, + ); return scope2; } @@ -333,8 +373,14 @@ _log('Fallback: use library scope for the Dart SDK'); scope = DartScope(library, null, null, {}, []); } else { - onDiagnostic(_createInternalError( - libraryUri, line, column, 'Dart scope not found for location')); + onDiagnostic( + _createInternalError( + libraryUri, + line, + column, + 'Dart scope not found for location', + ), + ); return null; } } @@ -360,14 +406,15 @@ } } var procedure = await _compiler.compileExpression( - expression, - scope.definitions, - scope.typeParameters, - debugProcedureName, - scope.library.importUri, - methodName: methodName, - className: scope.cls?.name, - isStatic: scope.isStatic); + expression, + scope.definitions, + scope.typeParameters, + debugProcedureName, + scope.library.importUri, + methodName: methodName, + className: scope.cls?.name, + isStatic: scope.isStatic, + ); _log('Compiled expression to kernel'); @@ -378,19 +425,26 @@ } var imports = <js_ast.ModuleItem>[]; - var jsFun = _kernel2jsCompiler.emitFunctionIncremental(imports, - scope.library, scope.cls, procedure!.function, debugProcedureName); + var jsFun = _kernel2jsCompiler.emitFunctionIncremental( + imports, + scope.library, + scope.cls, + procedure!.function, + debugProcedureName, + ); _log('Generated JavaScript for expression'); // print JS ast to string for evaluation var context = js_ast.SimpleJavaScriptPrintingContext(); - var opts = - js_ast.JavaScriptPrintingOptions(allowKeywordsInProperties: true); + var opts = js_ast.JavaScriptPrintingOptions( + allowKeywordsInProperties: true, + ); var tree = transformFunctionModuleFormat(imports, jsFun, _moduleFormat); tree.accept( - js_ast.Printer(opts, context, localNamer: js_ast.ScopedNamer(tree))); + js_ast.Printer(opts, context, localNamer: js_ast.ScopedNamer(tree)), + ); _log('Added imports and renamed variables for expression');
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart index 33dab21..99320ba 100644 --- a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart +++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
@@ -120,20 +120,27 @@ /// /// The worker stops on start failure or after the consumer closes its /// receive port corresponding to [sendPort]. - static Future<void> createAndStart(List<String> args, - {SendPort? sendPort}) async { + static Future<void> createAndStart( + List<String> args, { + SendPort? sendPort, + }) async { ExpressionCompilerWorker? worker; if (sendPort != null) { var receivePort = ReceivePort(); sendPort.send(receivePort.sendPort); try { - worker = await createFromArgs(args, - requestStream: receivePort.cast<Map<String, dynamic>>(), - sendResponse: sendPort.send); + worker = await createFromArgs( + args, + requestStream: receivePort.cast<Map<String, dynamic>>(), + sendResponse: sendPort.send, + ); await worker.run(); } catch (e, s) { - sendPort - .send({'exception': '$e', 'stackTrace': '$s', 'succeeded': false}); + sendPort.send({ + 'exception': '$e', + 'stackTrace': '$s', + 'succeeded': false, + }); rethrow; } finally { receivePort.close(); @@ -172,18 +179,24 @@ if (assetServerAddress != null) { var assetServerPort = parsedArgs['asset-server-port'] as String?; fileSystem = AssetFileSystem( - fileSystem, assetServerAddress, assetServerPort ?? '8080'); + fileSystem, + assetServerAddress, + assetServerPort ?? '8080', + ); } var explicitExperimentalFlags = parseExperimentalFlags( - parseExperimentalArguments( - parsedArgs['enable-experiment'] as List<String>), - onError: (e) => throw e); + parseExperimentalArguments( + parsedArgs['enable-experiment'] as List<String>, + ), + onError: (e) => throw e, + ); var moduleFormat = parseModuleFormat(parsedArgs['module-format'] as String); return create( - librariesSpecificationUri: - _argToUri(parsedArgs['libraries-file'] as String?), + librariesSpecificationUri: _argToUri( + parsedArgs['libraries-file'] as String?, + ), packagesFile: _argToUri(parsedArgs['packages-file'] as String?), sdkSummary: _argToUri(parsedArgs['dart-sdk-summary'] as String?), fileSystem: fileSystem, @@ -223,7 +236,7 @@ bool verbose = false, Stream<Map<String, dynamic>>? requestStream, // Defaults to read from stdin void Function(Map<String, dynamic>)? - sendResponse, // Defaults to write to stdout + sendResponse, // Defaults to write to stdout void Function()? onDone, }) async { var compilerOptions = CompilerOptions() @@ -233,7 +246,8 @@ ..packagesFileUri = packagesFile ..librariesSpecificationUri = librariesSpecificationUri ..target = DevCompilerTarget( - TargetFlags(trackWidgetCreation: trackWidgetCreation)) + TargetFlags(trackWidgetCreation: trackWidgetCreation), + ) ..fileSystem = fileSystem ..omitPlatform = true ..environmentDefines = addGeneratedVariables({ @@ -251,23 +265,23 @@ var sdkComponent = await CompilerContext(processedOptions) .runInContext<Component?>((CompilerContext c) async { - return processedOptions.loadSdkSummary(null); - }); + return processedOptions.loadSdkSummary(null); + }); if (sdkComponent == null) { throw Exception('Could not load SDK component: $sdkSummary'); } return ExpressionCompilerWorker._( - processedOptions, - compilerOptions, - moduleFormat, - canaryFeatures, - enableAsserts, - sdkComponent, - requestStream, - sendResponse, - onDone) - .._updateCache(sdkComponent, dartSdkModule, true); + processedOptions, + compilerOptions, + moduleFormat, + canaryFeatures, + enableAsserts, + sdkComponent, + requestStream, + sendResponse, + onDone, + ).._updateCache(sdkComponent, dartSdkModule, true); } /// Starts listening and responding to commands. @@ -281,19 +295,27 @@ if (command == 'Shutdown') break; switch (command) { case 'UpdateDeps': - sendResponse(await _updateDependencies( - UpdateDependenciesRequest.fromJson(request))); + sendResponse( + await _updateDependencies( + UpdateDependenciesRequest.fromJson(request), + ), + ); case 'CompileExpression': - sendResponse(await _compileExpression( - CompileExpressionRequest.fromJson(request))); + sendResponse( + await _compileExpression( + CompileExpressionRequest.fromJson(request), + ), + ); default: throw ArgumentError( - 'Unrecognized command `$command`, full request was `$request`'); + 'Unrecognized command `$command`, full request was `$request`', + ); } } catch (e, s) { var command = request['command'] as String?; - _processedOptions.ticker - .logMs('Expression compiler worker request $command failed: $e:$s'); + _processedOptions.ticker.logMs( + 'Expression compiler worker request $command failed: $e:$s', + ); sendResponse({ 'exception': '$e', 'stackTrace': '$s', @@ -314,7 +336,8 @@ /// Handles a `CompileExpression` request. Future<Map<String, dynamic>> _compileExpression( - CompileExpressionRequest request) async { + CompileExpressionRequest request, + ) async { var libraryUri = Uri.parse(request.libraryUri); var moduleName = request.moduleName; var isSdk = libraryUri.isScheme('dart'); @@ -333,8 +356,9 @@ throw Exception('Expression compilation inside SDK is not supported yet'); } - _processedOptions.ticker - .logMs('Compiling expression to JavaScript in module $moduleName'); + _processedOptions.ticker.logMs( + 'Compiling expression to JavaScript in module $moduleName', + ); // Reset linking of libraries to the original state, // so any newly loaded components are linked to the @@ -350,9 +374,14 @@ // Note that this doesn't actually reload it if it's already fully loaded. if (!await _loadAndUpdateComponent( - _fullModules[moduleName]!, moduleName, false)) { - throw ArgumentError('Failed to load full dill for module $moduleName: ' - '${_fullModules[moduleName]}'); + _fullModules[moduleName]!, + moduleName, + false, + )) { + throw ArgumentError( + 'Failed to load full dill for module $moduleName: ' + '${_fullModules[moduleName]}', + ); } } @@ -360,8 +389,10 @@ warnings.clear(); infos.clear(); - var expressionCompiler = - await _createExpressionCompiler(libraryUri, moduleName); + var expressionCompiler = await _createExpressionCompiler( + libraryUri, + moduleName, + ); // Failed to compile component, report compilation errors. if (expressionCompiler == null) { @@ -375,12 +406,13 @@ } var compiledProcedure = await expressionCompiler.compileExpressionToJs( - request.libraryUri, - request.scriptUri, - request.line, - request.column, - request.jsScope, - request.expression); + request.libraryUri, + request.scriptUri, + request.line, + request.column, + request.jsScope, + request.expression, + ); _processedOptions.ticker.logMs('Compiled expression to JavaScript'); @@ -398,12 +430,15 @@ /// [moduleName]. /// Returns `null` if the module's component compilation fails. Future<ExpressionCompiler?> _createExpressionCompiler( - Uri libraryUri, String moduleName) async { + Uri libraryUri, + String moduleName, + ) async { var expressionCompiler = _moduleCache.expressionCompilers[moduleName]; if (expressionCompiler != null) return expressionCompiler; - _processedOptions.ticker - .logMs('Creating expression compiler for $moduleName'); + _processedOptions.ticker.logMs( + 'Creating expression compiler for $moduleName', + ); var originalComponent = _moduleCache.componentForModuleName[moduleName]; if (originalComponent == null) { @@ -420,8 +455,10 @@ // here, instead. _processedOptions.ticker.logMs('Collecting libraries for $moduleName'); - var libraries = - _collectTransitiveDependencies(originalComponent, _sdkComponent); + var libraries = _collectTransitiveDependencies( + originalComponent, + _sdkComponent, + ); assert(!duplicateLibrariesReachable(libraries)); @@ -437,14 +474,19 @@ for (var library in originalComponent.libraries) // Filter out SDK libraries unless the goal is a library level // expression evaluation in the Dart SDK. - if (isSdk || !library.importUri.isScheme('dart')) library.importUri + if (isSdk || !library.importUri.isScheme('dart')) library.importUri, ]; var incrementalCompiler = IncrementalCompiler.forExpressionCompilationOnly( - CompilerContext(_processedOptions), component, /*resetTicker*/ false); + CompilerContext(_processedOptions), + component, + /*resetTicker*/ false, + ); var incrementalCompilerResult = await incrementalCompiler.computeDelta( - entryPoints: entryPoints, fullComponent: true); + entryPoints: entryPoints, + fullComponent: true, + ); var finalComponent = incrementalCompilerResult.component; assert(!duplicateLibrariesReachable(finalComponent.libraries)); assert(_canSerialize(finalComponent)); @@ -474,8 +516,10 @@ ticker: _processedOptions.ticker, ); - assert(originalComponent.libraries.toSet().length == - originalComponent.libraries.length); + assert( + originalComponent.libraries.toSet().length == + originalComponent.libraries.length, + ); // Pick the libraries from finalComponent that's also in originalComponent. // This is needed because originalComponent can contain unreachable things @@ -487,10 +531,10 @@ assert(_librariesAreKnown(hierarchy, librariesToEmit)); var componentToEmit = Component( - libraries: librariesToEmit, - nameRoot: finalComponent.root, - uriToSource: finalComponent.uriToSource) - ..setMainMethodAndMode(originalComponent.mainMethodName, true); + libraries: librariesToEmit, + nameRoot: finalComponent.root, + uriToSource: finalComponent.uriToSource, + )..setMainMethodAndMode(originalComponent.mainMethodName, true); kernel2jsCompiler.emitModule(componentToEmit); _processedOptions.ticker.logMs('Emitted module for expression'); @@ -506,14 +550,17 @@ finalComponent, ); _moduleCache.expressionCompilers[moduleName] = expressionCompiler; - _processedOptions.ticker - .logMs('Created expression compiler for $moduleName'); + _processedOptions.ticker.logMs( + 'Created expression compiler for $moduleName', + ); return expressionCompiler; } /// Collect libraries reachable from component. List<Library> _collectTransitiveDependencies( - Component component, Component sdk) { + Component component, + Component sdk, + ) { var visited = <Uri>{}; var libraries = <Library>[]; var toVisit = <Uri>[]; @@ -533,8 +580,9 @@ toVisit.add(dep.importedLibraryReference.asLibrary.importUri); } else { _processedOptions.ticker.logMs( - 'Missing link for ${dep.importedLibraryReference.canonicalName}' - ' in ${lib.importUri}'); + 'Missing link for ${dep.importedLibraryReference.canonicalName}' + ' in ${lib.importUri}', + ); } } } else { @@ -548,9 +596,11 @@ /// Loads in the specified dill files and invalidates any existing ones. Future<Map<String, dynamic>> _updateDependencies( - UpdateDependenciesRequest request) async { - _processedOptions.ticker - .logMs('Updating dependencies for expression evaluation'); + UpdateDependenciesRequest request, + ) async { + _processedOptions.ticker.logMs( + 'Updating dependencies for expression evaluation', + ); for (var input in request.inputs) { _clearCache(input.moduleName); @@ -573,25 +623,35 @@ // path by loading full dill kernel instead. var hasSummary = input.summaryPath != null; if (!hasSummary) { - _processedOptions.ticker - .logMs('Summary path is not provided for ${input.moduleName}.' - ' Loading full dill instead.'); + _processedOptions.ticker.logMs( + 'Summary path is not provided for ${input.moduleName}.' + ' Loading full dill instead.', + ); } var summaryPath = input.summaryPath ?? input.path; _fullModules[input.moduleName] = Uri.parse(input.path); - futures.add(_loadAndUpdateComponent( - Uri.parse(summaryPath), input.moduleName, hasSummary)); + futures.add( + _loadAndUpdateComponent( + Uri.parse(summaryPath), + input.moduleName, + hasSummary, + ), + ); } await Future.wait(futures); - _processedOptions.ticker - .logMs('Updated dependencies for expression evaluation'); + _processedOptions.ticker.logMs( + 'Updated dependencies for expression evaluation', + ); return {'succeeded': true}; } /// Load component and update cache. Future<bool> _loadAndUpdateComponent( - Uri uri, String moduleName, bool isSummary) async { + Uri uri, + String moduleName, + bool isSummary, + ) async { if (isSummary && _moduleCache.isModuleLoaded(moduleName)) return true; if (!isSummary && _moduleCache.isModuleFullyLoaded(moduleName)) return true; var componentKind = isSummary ? 'summary' : 'full kernel'; @@ -599,8 +659,9 @@ _processedOptions.ticker.logMs('Loading $componentKind for $moduleName'); var component = await _loadComponent(uri); if (component == null) { - _processedOptions.ticker - .logMs('Failed to load $componentKind for $moduleName'); + _processedOptions.ticker.logMs( + 'Failed to load $componentKind for $moduleName', + ); return false; } _updateCache(component, moduleName, isSummary); @@ -611,8 +672,11 @@ var file = _processedOptions.fileSystem.entityForUri(uri); if (await file.existsAsyncIfPossible()) { var bytes = await file.readAsBytesAsyncIfPossible(); - var component = _processedOptions.loadComponent(bytes, _sdkComponent.root, - alwaysCreateNewNamedNodes: true); + var component = _processedOptions.loadComponent( + bytes, + _sdkComponent.root, + alwaysCreateNewNamedNodes: true, + ); return component; } _processedOptions.ticker.logMs('File for $uri does not exist.'); @@ -692,8 +756,10 @@ for (var lib in component.libraries) { if (isLibraryLoaded(lib)) { - throw Exception('library ${lib.importUri} is already loaded in ' - '${moduleNameForComponent[componentForLibrary[lib]!]}'); + throw Exception( + 'library ${lib.importUri} is already loaded in ' + '${moduleNameForComponent[componentForLibrary[lib]!]}', + ); } componentForLibrary[lib] = component; libraryForUri[lib.importUri] = lib; @@ -760,8 +826,11 @@ factory UpdateDependenciesRequest.fromJson(Map<String, dynamic> json) => UpdateDependenciesRequest([ for (var input in json['inputs'] as List) - InputDill(input['path'] as String, input['summaryPath'] as String, - input['moduleName'] as String), + InputDill( + input['path'] as String, + input['summaryPath'] as String, + input['moduleName'] as String, + ), ]); } @@ -774,26 +843,30 @@ } void Function(DiagnosticMessage) _onDiagnosticHandler( - List<String> errors, List<String> warnings, List<String> infos) => - (DiagnosticMessage message) { - switch (message.severity) { - case Severity.error: - case Severity.internalProblem: - errors.add(message.plainTextFormatted.join('\n')); - case Severity.warning: - warnings.add(message.plainTextFormatted.join('\n')); - case Severity.info: - infos.add(message.plainTextFormatted.join('\n')); - case Severity.context: - case Severity.ignored: - throw 'Unexpected severity: ${message.severity}'; - } - }; + List<String> errors, + List<String> warnings, + List<String> infos, +) => (DiagnosticMessage message) { + switch (message.severity) { + case Severity.error: + case Severity.internalProblem: + errors.add(message.plainTextFormatted.join('\n')); + case Severity.warning: + warnings.add(message.plainTextFormatted.join('\n')); + case Severity.info: + infos.add(message.plainTextFormatted.join('\n')); + case Severity.context: + case Severity.ignored: + throw 'Unexpected severity: ${message.severity}'; + } +}; final argParser = ArgParser() ..addOption('dart-sdk-summary') - ..addMultiOption('enable-experiment', - help: 'Enable a language experiment when invoking the CFE.') + ..addMultiOption( + 'enable-experiment', + help: 'Enable a language experiment when invoking the CFE.', + ) ..addOption('libraries-file') ..addMultiOption('multi-root') ..addOption('multi-root-scheme', defaultsTo: 'org-dartlang-app')
diff --git a/pkg/dev_compiler/lib/src/kernel/future_or_normalizer.dart b/pkg/dev_compiler/lib/src/kernel/future_or_normalizer.dart index 5541e79..1e22604 100644 --- a/pkg/dev_compiler/lib/src/kernel/future_or_normalizer.dart +++ b/pkg/dev_compiler/lib/src/kernel/future_or_normalizer.dart
@@ -44,24 +44,28 @@ case InterfaceType() when typeArgument.classNode == _coreTypes.objectClass: // Normalize FutureOr of Object, Object?, Object*. - var nullable = futureOr.nullability == Nullability.nullable || + var nullable = + futureOr.nullability == Nullability.nullable || typeArgument.nullability == Nullability.nullable; - var legacy = futureOr.nullability == Nullability.legacy || + var legacy = + futureOr.nullability == Nullability.legacy || typeArgument.nullability == Nullability.legacy; var nullability = nullable ? Nullability.nullable : legacy - ? Nullability.legacy - : Nullability.nonNullable; + ? Nullability.legacy + : Nullability.nonNullable; return typeArgument.withDeclaredNullability(nullability); case NeverType() when typeArgument.nullability == Nullability.nonNullable: // FutureOr<Never> --> Future<Never> - return InterfaceType( - _coreTypes.futureClass, futureOr.nullability, [typeArgument]); + return InterfaceType(_coreTypes.futureClass, futureOr.nullability, [ + typeArgument, + ]); case NullType(): // FutureOr<Null> --> Future<Null>? - return InterfaceType( - _coreTypes.futureClass, Nullability.nullable, [typeArgument]); + return InterfaceType(_coreTypes.futureClass, Nullability.nullable, [ + typeArgument, + ]); case InterfaceType(): case NeverType(): case FunctionType(): @@ -96,7 +100,8 @@ } case ExtensionType(): throw UnsupportedError( - '`ExtensionType`s must be erased before `FutureOr` normalization.'); + '`ExtensionType`s must be erased before `FutureOr` normalization.', + ); case AuxiliaryType(): throwUnsupportedAuxiliaryType(typeArgument); case InvalidType():
diff --git a/pkg/dev_compiler/lib/src/kernel/hot_reload_delta_inspector.dart b/pkg/dev_compiler/lib/src/kernel/hot_reload_delta_inspector.dart index 0faf5b5..643d0ef 100644 --- a/pkg/dev_compiler/lib/src/kernel/hot_reload_delta_inspector.dart +++ b/pkg/dev_compiler/lib/src/kernel/hot_reload_delta_inspector.dart
@@ -33,39 +33,49 @@ /// compiling. List<String> compareGenerations(Component lastAccepted, Component delta) { final deltaLibraryImportUris = [ - for (var library in delta.libraries) '${library.importUri}' + for (var library in delta.libraries) '${library.importUri}', ]; - _partialLastAcceptedLibraryIndex = - LibraryIndex(lastAccepted, deltaLibraryImportUris); + _partialLastAcceptedLibraryIndex = LibraryIndex( + lastAccepted, + deltaLibraryImportUris, + ); final deltaLibraryIndex = LibraryIndex(delta, deltaLibraryImportUris); - final metadataRepo = lastAccepted.metadata[hotReloadLibraryMetadataTag] + final metadataRepo = + lastAccepted.metadata[hotReloadLibraryMetadataTag] as HotReloadLibraryMetadataRepository? ?? HotReloadLibraryMetadataRepository(); metadataRepo.generation++; _rejectionMessages.clear(); for (var deltaLibrary in delta.libraries) { - final acceptedLibrary = _partialLastAcceptedLibraryIndex - .tryGetLibrary('${deltaLibrary.importUri}'); + final acceptedLibrary = _partialLastAcceptedLibraryIndex.tryGetLibrary( + '${deltaLibrary.importUri}', + ); if (acceptedLibrary == null) { // No previous version of the library to compare with. continue; } if (_shouldNotCompileWithHotReload(deltaLibrary.importUri)) { - _rejectionMessages - .add('Attempting to hot reload a modified library from a package ' - 'marked as non-hot-reloadable: ' - "Library: '${deltaLibrary.importUri}'"); + _rejectionMessages.add( + 'Attempting to hot reload a modified library from a package ' + 'marked as non-hot-reloadable: ' + "Library: '${deltaLibrary.importUri}'", + ); } - var libraryMetadata = metadataRepo.mapping - .putIfAbsent(deltaLibrary, HotReloadLibraryMetadata.new); + var libraryMetadata = metadataRepo.mapping.putIfAbsent( + deltaLibrary, + HotReloadLibraryMetadata.new, + ); // TODO(60281): Handle members when an entire library has been deleted // from the delta. libraryMetadata.deletedStaticProcedureNames.clear(); libraryMetadata.deletedStaticProcedureNames.addAll( - _findDeletedLibraryProcedures(acceptedLibrary, deltaLibraryIndex)); + _findDeletedLibraryProcedures(acceptedLibrary, deltaLibraryIndex), + ); for (var deltaClass in deltaLibrary.classes) { final acceptedClass = _partialLastAcceptedLibraryIndex.tryGetClass( - '${deltaLibrary.importUri}', deltaClass.name); + '${deltaLibrary.importUri}', + deltaClass.name, + ); if (acceptedClass == null) { // No previous version of the class to compare with. continue; @@ -97,9 +107,11 @@ void _checkConstClassConsistency(Class acceptedClass, Class deltaClass) { assert(acceptedClass.hasConstConstructor); if (!deltaClass.hasConstConstructor) { - _rejectionMessages.add('Const class cannot become non-const: ' - "Library:'${deltaClass.enclosingLibrary.importUri}' " - 'Class: ${deltaClass.name}'); + _rejectionMessages.add( + 'Const class cannot become non-const: ' + "Library:'${deltaClass.enclosingLibrary.importUri}' " + 'Class: ${deltaClass.name}', + ); } } @@ -118,13 +130,15 @@ } // Verify all fields are still present. final acceptedFields = { - for (var field in acceptedClass.fields) field.name.text + for (var field in acceptedClass.fields) field.name.text, }; final deltaFields = {for (var field in deltaClass.fields) field.name.text}; if (acceptedFields.difference(deltaFields).isNotEmpty) { - _rejectionMessages.add('Const class cannot remove fields: ' - "Library:'${deltaClass.enclosingLibrary.importUri}' " - 'Class: ${deltaClass.name}'); + _rejectionMessages.add( + 'Const class cannot remove fields: ' + "Library:'${deltaClass.enclosingLibrary.importUri}' " + 'Class: ${deltaClass.name}', + ); } } @@ -134,13 +148,16 @@ /// [acceptedClass] and [deltaClass] must represent the same class in the /// last known accepted and delta components respectively. void _checkClassTypeParametersCountChange( - Class acceptedClass, Class deltaClass) { + Class acceptedClass, + Class deltaClass, + ) { if (acceptedClass.typeParameters.length != deltaClass.typeParameters.length) { _rejectionMessages.add( - 'Limitation: changing type parameters does not work with hot reload.' - "Library:'${deltaClass.enclosingLibrary.importUri}' " - 'Class: ${deltaClass.name}'); + 'Limitation: changing type parameters does not work with hot reload.' + "Library:'${deltaClass.enclosingLibrary.importUri}' " + 'Class: ${deltaClass.name}', + ); } } @@ -150,24 +167,32 @@ /// last known accepted and delta components respectively. void _checkEnumIllegalConversion(Class acceptedClass, Class deltaClass) { if (acceptedClass.isEnum && !deltaClass.isEnum) { - _rejectionMessages - .add('Enum class cannot be redefined to be a non-enum class.' - 'Class: ${deltaClass.name}'); + _rejectionMessages.add( + 'Enum class cannot be redefined to be a non-enum class.' + 'Class: ${deltaClass.name}', + ); } else if (!acceptedClass.isEnum && deltaClass.isEnum) { - _rejectionMessages.add('Class cannot be redefined to be a enum class.' - 'Class: ${deltaClass.name}'); + _rejectionMessages.add( + 'Class cannot be redefined to be a enum class.' + 'Class: ${deltaClass.name}', + ); } } /// Returns the names of library methods, getters, and setters that were /// present in [acceptedLibrary] but do not appear in [deltaLibraryIndex]. List<String> _findDeletedLibraryProcedures( - Library acceptedLibrary, LibraryIndex deltaLibraryIndex) { + Library acceptedLibrary, + LibraryIndex deltaLibraryIndex, + ) { final acceptedLibraryImportUri = '${acceptedLibrary.importUri}'; return [ for (var acceptedProcedure in acceptedLibrary.procedures) - if (deltaLibraryIndex.tryGetProcedure(acceptedLibraryImportUri, - LibraryIndex.topLevel, acceptedProcedure.indexName) == + if (deltaLibraryIndex.tryGetProcedure( + acceptedLibraryImportUri, + LibraryIndex.topLevel, + acceptedProcedure.indexName, + ) == null) acceptedProcedure.name.text, ]; @@ -212,7 +237,10 @@ @override void writeToBinary( - HotReloadLibraryMetadata metadata, Node node, BinarySink sink) { + HotReloadLibraryMetadata metadata, + Node node, + BinarySink sink, + ) { // TODO(nshahan): How to write all metadata even when there are no // associated nodes. } @@ -255,7 +283,7 @@ void encodeMapping() { _encodedMetadata.addAll({ for (var library in mapping.keys) - '${library.importUri}': mapping[library]! + '${library.importUri}': mapping[library]!, }); mapping.clear(); }
diff --git a/pkg/dev_compiler/lib/src/kernel/js_interop.dart b/pkg/dev_compiler/lib/src/kernel/js_interop.dart index 5c4ef90..0888352 100644 --- a/pkg/dev_compiler/lib/src/kernel/js_interop.dart +++ b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
@@ -26,16 +26,16 @@ /// `dart:_foreign_helper`, `dart:_js_annotations`, or `dart:_js_helper`, or /// `dart:js_interop`. bool _isJSLibrary(Library library) => _isLibrary(library, [ - // While the annotations no longer live in `package:js`, this is needed to - // support older versions of the package. - 'package:js', - 'dart:_foreign_helper', - 'dart:_js_annotations', - 'dart:_js_helper', - // This is to allow `dart:js_interop`'s `@JS` to work with - // `@staticInterop`. - 'dart:js_interop', - ]); + // While the annotations no longer live in `package:js`, this is needed to + // support older versions of the package. + 'package:js', + 'dart:_foreign_helper', + 'dart:_js_annotations', + 'dart:_js_helper', + // This is to allow `dart:js_interop`'s `@JS` to work with + // `@staticInterop`. + 'dart:js_interop', +]); /// Whether [node] is a direct call to `allowInterop`. bool isAllowInterop(Expression node) {
diff --git a/pkg/dev_compiler/lib/src/kernel/js_typerep.dart b/pkg/dev_compiler/lib/src/kernel/js_typerep.dart index 1143af8..3a4e827 100644 --- a/pkg/dev_compiler/lib/src/kernel/js_typerep.dart +++ b/pkg/dev_compiler/lib/src/kernel/js_typerep.dart
@@ -20,13 +20,16 @@ final Class _jsString; JSTypeRep(this.types, this.hierarchy) - : coreTypes = types.coreTypes, - _jsBool = - types.coreTypes.index.getClass('dart:_interceptors', 'JSBool'), - _jsNumber = - types.coreTypes.index.getClass('dart:_interceptors', 'JSNumber'), - _jsString = - types.coreTypes.index.getClass('dart:_interceptors', 'JSString'); + : coreTypes = types.coreTypes, + _jsBool = types.coreTypes.index.getClass('dart:_interceptors', 'JSBool'), + _jsNumber = types.coreTypes.index.getClass( + 'dart:_interceptors', + 'JSNumber', + ), + _jsString = types.coreTypes.index.getClass( + 'dart:_interceptors', + 'JSString', + ); @override JSType typeFor(DartType type) {
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart index 9903e17..83d136d 100644 --- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart +++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -11,11 +11,13 @@ import 'constants.dart'; Never throwUnsupportedInvalidType(InvalidType type) => throw UnsupportedError( - 'Unsupported invalid type $type (${type.runtimeType}).'); + 'Unsupported invalid type $type (${type.runtimeType}).', +); Never throwUnsupportedAuxiliaryType(AuxiliaryType type) => throw UnsupportedError( - 'Unsupported auxiliary type $type (${type.runtimeType}).'); + 'Unsupported auxiliary type $type (${type.runtimeType}).', + ); Constructor? unnamedConstructor(Class c) => c.constructors.firstWhereOrNull((c) => c.name.text == ''); @@ -56,7 +58,8 @@ /// Returns the escaped name for the type parameter [node]. String getTypeParameterName( - /* TypeParameter | StructuralParameter */ Object node) { + /* TypeParameter | StructuralParameter */ Object node, +) { assert(node is TypeParameter || node is StructuralParameter); if (node is TypeParameter) { return escapeIdentifier(node.name!); @@ -108,7 +111,10 @@ /// Returns true if [value] represents an annotation for class [className] in /// "dart:" library [libraryName]. bool isBuiltinAnnotation( - Expression value, String libraryName, String className) { + Expression value, + String libraryName, + String className, +) { var c = getAnnotationClass(value); if (c != null && c.name == className) { var uri = c.enclosingLibrary.importUri; @@ -599,8 +605,10 @@ // The variable is an argument of the function to be inlined. Verify it // appears in an order consistent with the order the arguments appeared // in the call. - final location = - _expectedArgumentOrder!.indexOf(node.variable, _nextArgIndex); + final location = _expectedArgumentOrder!.indexOf( + node.variable, + _nextArgIndex, + ); // Either the variable isn't one of the expected arguments at all, or it is // appearing out of the expected order. if (location == -1) return false;
diff --git a/pkg/dev_compiler/lib/src/kernel/module_metadata.dart b/pkg/dev_compiler/lib/src/kernel/module_metadata.dart index 6b2d0e4..50ff8c2 100644 --- a/pkg/dev_compiler/lib/src/kernel/module_metadata.dart +++ b/pkg/dev_compiler/lib/src/kernel/module_metadata.dart
@@ -41,8 +41,10 @@ bool isCompatibleWith(String version) { var parts = version.split('.'); if (parts.length != 3) { - throw FormatException('Version: $version' - 'does not follow simple semantic versioning format'); + throw FormatException( + 'Version: $version' + 'does not follow simple semantic versioning format', + ); } var major = int.parse(parts[0]); var minor = int.parse(parts[1]); @@ -79,18 +81,19 @@ LibraryMetadata(this.name, this.importUri, this.fileUri, this.partUris); LibraryMetadata.fromJson(Map<String, dynamic> json) - : name = json['name'] as String, - importUri = json['importUri'] as String, - fileUri = json['fileUri'] as String, - partUris = - List.castFrom<dynamic, String>(json['partUris'] as List<dynamic>); + : name = json['name'] as String, + importUri = json['importUri'] as String, + fileUri = json['fileUri'] as String, + partUris = List.castFrom<dynamic, String>( + json['partUris'] as List<dynamic>, + ); Map<String, dynamic> toJson() { return { 'name': name, 'importUri': importUri, 'fileUri': fileUri, - 'partUris': [...partUris] + 'partUris': [...partUris], }; } } @@ -127,10 +130,14 @@ final Map<String, LibraryMetadata> libraries = {}; - ModuleMetadata(this.name, this.closureName, this.sourceMapUri, this.moduleUri, - this.fullDillUri, - {String? version}) - : version = version ??= ModuleMetadataVersion.current.version; + ModuleMetadata( + this.name, + this.closureName, + this.sourceMapUri, + this.moduleUri, + this.fullDillUri, { + String? version, + }) : version = version ??= ModuleMetadataVersion.current.version; /// Add [library] to this metadata. /// @@ -148,12 +155,12 @@ } ModuleMetadata.fromJson(Map<String, dynamic> json) - : version = json['version'] as String, - name = json['name'] as String, - closureName = json['closureName'] as String, - sourceMapUri = json['sourceMapUri'] as String, - moduleUri = json['moduleUri'] as String, - fullDillUri = json['fullDillUri'] as String { + : version = json['version'] as String, + name = json['name'] as String, + closureName = json['closureName'] as String, + sourceMapUri = json['sourceMapUri'] as String, + moduleUri = json['moduleUri'] as String, + fullDillUri = json['fullDillUri'] as String { if (!ModuleMetadataVersion.current.isCompatibleWith(version)) { throw Exception('Unsupported metadata version $version'); } @@ -171,7 +178,7 @@ 'sourceMapUri': sourceMapUri, 'moduleUri': moduleUri, 'fullDillUri': fullDillUri, - 'libraries': [for (var lib in libraries.values) lib.toJson()] + 'libraries': [for (var lib in libraries.values) lib.toJson()], }; } }
diff --git a/pkg/dev_compiler/lib/src/kernel/module_symbols.dart b/pkg/dev_compiler/lib/src/kernel/module_symbols.dart index fcd5684..263cb25 100644 --- a/pkg/dev_compiler/lib/src/kernel/module_symbols.dart +++ b/pkg/dev_compiler/lib/src/kernel/module_symbols.dart
@@ -44,16 +44,14 @@ final int major; final int minor; final int patch; - const SemanticVersion( - this.major, - this.minor, - this.patch, - ); + const SemanticVersion(this.major, this.minor, this.patch); static SemanticVersion parse(String version) { var parts = version.split('.'); if (parts.length != 3) { - throw FormatException('Version: $version ' - 'does not follow simple semantic versioning format'); + throw FormatException( + 'Version: $version ' + 'does not follow simple semantic versioning format', + ); } var major = int.parse(parts[0]); var minor = int.parse(parts[1]); @@ -130,29 +128,28 @@ List<FunctionSymbol>? functions, List<ScopeSymbol>? scopes, List<VariableSymbol>? variables, - }) : version = version ??= current.version, - libraries = libraries ?? [], - scripts = scripts ?? [], - classes = classes ?? [], - functionTypes = functionTypes ?? [], - functions = functions ?? [], - scopes = scopes ?? [], - variables = variables ?? []; + }) : version = version ??= current.version, + libraries = libraries ?? [], + scripts = scripts ?? [], + classes = classes ?? [], + functionTypes = functionTypes ?? [], + functions = functions ?? [], + scopes = scopes ?? [], + variables = variables ?? []; ModuleSymbols.fromJson(Map<String, dynamic> json) - : version = _readAndValidateVersionFromJson(json['version']), - moduleName = _createValue(json['moduleName']), - libraries = - _createObjectList(json['libraries'], LibrarySymbol.fromJson), - scripts = _createObjectList(json['scripts'], Script.fromJson), - classes = _createObjectList(json['classes'], ClassSymbol.fromJson), - functionTypes = _createObjectList( - json['functionTypes'], FunctionTypeSymbol.fromJson), - functions = - _createObjectList(json['functions'], FunctionSymbol.fromJson), - scopes = _createObjectList(json['scopes'], ScopeSymbol.fromJson), - variables = - _createObjectList(json['variables'], VariableSymbol.fromJson); + : version = _readAndValidateVersionFromJson(json['version']), + moduleName = _createValue(json['moduleName']), + libraries = _createObjectList(json['libraries'], LibrarySymbol.fromJson), + scripts = _createObjectList(json['scripts'], Script.fromJson), + classes = _createObjectList(json['classes'], ClassSymbol.fromJson), + functionTypes = _createObjectList( + json['functionTypes'], + FunctionTypeSymbol.fromJson, + ), + functions = _createObjectList(json['functions'], FunctionSymbol.fromJson), + scopes = _createObjectList(json['scopes'], ScopeSymbol.fromJson), + variables = _createObjectList(json['variables'], VariableSymbol.fromJson); @override Map<String, dynamic> toJson() { @@ -174,8 +171,10 @@ if (json == null) return current.version; var version = _createValue<String>(json); if (!current.isCompatibleWith(version)) { - throw Exception('Unsupported version $version. ' - 'Current version: ${current.version}'); + throw Exception( + 'Unsupported version $version. ' + 'Current version: ${current.version}', + ); } return version; } @@ -203,10 +202,12 @@ Symbol({required this.localId, this.scopeId, this.location}); Symbol.fromJson(Map<String, dynamic> json) - : localId = _createValue(json['localId']), - scopeId = _createValue(json['scopeId']), - location = - _createNullableObject(json['location'], SourceLocation.fromJson); + : localId = _createValue(json['localId']), + scopeId = _createValue(json['scopeId']), + location = _createNullableObject( + json['location'], + SourceLocation.fromJson, + ); @override Map<String, dynamic> toJson() { @@ -226,10 +227,12 @@ enum VariableSymbolKind { global, local, property, field, formal, none } VariableSymbolKind parseVariableSymbolKind(String value) { - return VariableSymbolKind.values.singleWhere((e) => value == '$e', - orElse: () { - throw ArgumentError('$value is not VariableSymbolKind'); - }); + return VariableSymbolKind.values.singleWhere( + (e) => value == '$e', + orElse: () { + throw ArgumentError('$value is not VariableSymbolKind'); + }, + ); } class VariableSymbol extends Symbol { @@ -271,34 +274,37 @@ required super.localId, required String super.scopeId, required SourceLocation super.location, - }) : isConst = isConst ?? false, - isFinal = isFinal ?? false, - isStatic = isStatic ?? false; + }) : isConst = isConst ?? false, + isFinal = isFinal ?? false, + isStatic = isStatic ?? false; VariableSymbol.fromJson(super.json) - : name = _createValue(json['name']), - kind = _createValue(json['kind'], - parse: parseVariableSymbolKind, ifNull: VariableSymbolKind.none), - typeId = _createValue(json['typeId']), - isConst = _createValue(json['isConst']), - isFinal = _createValue(json['isFinal']), - isStatic = _createValue(json['isStatic']), - getterId = _createValue(json['getterId']), - setterId = _createValue(json['setterId']), - super.fromJson(); + : name = _createValue(json['name']), + kind = _createValue( + json['kind'], + parse: parseVariableSymbolKind, + ifNull: VariableSymbolKind.none, + ), + typeId = _createValue(json['typeId']), + isConst = _createValue(json['isConst']), + isFinal = _createValue(json['isFinal']), + isStatic = _createValue(json['isStatic']), + getterId = _createValue(json['getterId']), + setterId = _createValue(json['setterId']), + super.fromJson(); @override Map<String, dynamic> toJson() => { - ...super.toJson(), - 'name': name, - 'kind': kind.toString(), - if (typeId != null) 'typeId': typeId, - 'isConst': isConst, - 'isFinal': isFinal, - 'isStatic': isStatic, - if (getterId != null) 'getterId': getterId, - if (setterId != null) 'setterId': setterId, - }; + ...super.toJson(), + 'name': name, + 'kind': kind.toString(), + if (typeId != null) 'typeId': typeId, + 'isConst': isConst, + 'isFinal': isFinal, + 'isStatic': isStatic, + if (getterId != null) 'getterId': getterId, + if (setterId != null) 'setterId': setterId, + }; } class ClassSymbol extends ScopeSymbol implements TypeSymbol { @@ -348,30 +354,30 @@ required SourceLocation super.location, super.variableIds, super.scopeIds, - }) : isAbstract = isAbstract ?? false, - isConst = isConst ?? false, - interfaceIds = interfaceIds ?? [], - typeParameters = typeParameters ?? {}; + }) : isAbstract = isAbstract ?? false, + isConst = isConst ?? false, + interfaceIds = interfaceIds ?? [], + typeParameters = typeParameters ?? {}; ClassSymbol.fromJson(super.json) - : name = _createValue(json['name']), - isAbstract = _createValue(json['isAbstract']), - isConst = _createValue(json['isConst']), - superClassId = _createValue(json['superClassId']), - interfaceIds = _createValueList(json['interfaceIds']), - typeParameters = _createValueMap(json['typeParameters']), - super.fromJson(); + : name = _createValue(json['name']), + isAbstract = _createValue(json['isAbstract']), + isConst = _createValue(json['isConst']), + superClassId = _createValue(json['superClassId']), + interfaceIds = _createValueList(json['interfaceIds']), + typeParameters = _createValueMap(json['typeParameters']), + super.fromJson(); @override Map<String, dynamic> toJson() => { - ...super.toJson(), - 'name': name, - 'isAbstract': isAbstract, - 'isConst': isConst, - if (superClassId != null) 'superClassId': superClassId, - if (interfaceIds.isNotEmpty) 'interfaceIds': interfaceIds, - if (typeParameters.isNotEmpty) 'typeParameters': typeParameters, - }; + ...super.toJson(), + 'name': name, + 'isAbstract': isAbstract, + 'isConst': isConst, + if (superClassId != null) 'superClassId': superClassId, + if (interfaceIds.isNotEmpty) 'interfaceIds': interfaceIds, + if (typeParameters.isNotEmpty) 'typeParameters': typeParameters, + }; } class FunctionTypeSymbol extends Symbol implements TypeSymbol { @@ -399,31 +405,32 @@ required super.localId, required String super.scopeId, required SourceLocation super.location, - }) : typeParameters = typeParameters ?? {}, - parameterTypeIds = parameterTypeIds ?? [], - optionalParameterTypeIds = optionalParameterTypeIds ?? [], - namedParameterTypeIds = namedParameterTypeIds ?? {}; + }) : typeParameters = typeParameters ?? {}, + parameterTypeIds = parameterTypeIds ?? [], + optionalParameterTypeIds = optionalParameterTypeIds ?? [], + namedParameterTypeIds = namedParameterTypeIds ?? {}; FunctionTypeSymbol.fromJson(super.json) - : parameterTypeIds = _createValueList(json['parameterTypeIds']), - optionalParameterTypeIds = - _createValueList(json['optionalParameterTypeIds']), - typeParameters = _createValueMap(json['typeParameters']), - namedParameterTypeIds = _createValueMap(json['namedParameterTypeIds']), - returnTypeId = _createValue(json['returnTypeId']), - super.fromJson(); + : parameterTypeIds = _createValueList(json['parameterTypeIds']), + optionalParameterTypeIds = _createValueList( + json['optionalParameterTypeIds'], + ), + typeParameters = _createValueMap(json['typeParameters']), + namedParameterTypeIds = _createValueMap(json['namedParameterTypeIds']), + returnTypeId = _createValue(json['returnTypeId']), + super.fromJson(); @override Map<String, dynamic> toJson() => { - ...super.toJson(), - if (typeParameters.isNotEmpty) 'typeParameters': typeParameters, - if (parameterTypeIds.isNotEmpty) 'parameterTypeIds': parameterTypeIds, - if (optionalParameterTypeIds.isNotEmpty) - 'optionalParameterTypeIds': optionalParameterTypeIds, - if (namedParameterTypeIds.isNotEmpty) - 'namedParameterTypeIds': namedParameterTypeIds, - 'returnTypeId': returnTypeId, - }; + ...super.toJson(), + if (typeParameters.isNotEmpty) 'typeParameters': typeParameters, + if (parameterTypeIds.isNotEmpty) 'parameterTypeIds': parameterTypeIds, + if (optionalParameterTypeIds.isNotEmpty) + 'optionalParameterTypeIds': optionalParameterTypeIds, + if (namedParameterTypeIds.isNotEmpty) + 'namedParameterTypeIds': namedParameterTypeIds, + 'returnTypeId': returnTypeId, + }; } class FunctionSymbol extends ScopeSymbol { @@ -458,24 +465,24 @@ super.variableIds, super.scopeIds, required SourceLocation super.location, - }) : isStatic = isStatic ?? false, - isConst = isConst ?? false; + }) : isStatic = isStatic ?? false, + isConst = isConst ?? false; FunctionSymbol.fromJson(super.json) - : name = _createValue(json['name']), - typeId = _createValue(json['typeId']), - isStatic = _createValue(json['isStatic']), - isConst = _createValue(json['isConst']), - super.fromJson(); + : name = _createValue(json['name']), + typeId = _createValue(json['typeId']), + isStatic = _createValue(json['isStatic']), + isConst = _createValue(json['isConst']), + super.fromJson(); @override Map<String, dynamic> toJson() => { - ...super.toJson(), - 'name': name, - if (typeId != null) 'typeId': typeId, - 'isStatic': isStatic, - 'isConst': isConst, - }; + ...super.toJson(), + 'name': name, + if (typeId != null) 'typeId': typeId, + 'isStatic': isStatic, + 'isConst': isConst, + }; } class LibrarySymbol extends ScopeSymbol { @@ -498,19 +505,19 @@ required this.scriptIds, super.variableIds, super.scopeIds, - }) : name = name ?? '', - dependencies = dependencies ?? [], - super( - localId: uri, - ); + }) : name = name ?? '', + dependencies = dependencies ?? [], + super(localId: uri); LibrarySymbol.fromJson(super.json) - : name = _createValue(json['name'], ifNull: ''), - uri = _createValue(json['uri']), - scriptIds = _createValueList(json['scriptIds']), - dependencies = _createObjectList( - json['dependencies'], LibrarySymbolDependency.fromJson), - super.fromJson(); + : name = _createValue(json['name'], ifNull: ''), + uri = _createValue(json['uri']), + scriptIds = _createValueList(json['scriptIds']), + dependencies = _createObjectList( + json['dependencies'], + LibrarySymbolDependency.fromJson, + ), + super.fromJson(); @override Map<String, dynamic> toJson() { @@ -546,18 +553,18 @@ }) : isDeferred = isDeferred ?? false; LibrarySymbolDependency.fromJson(Map<String, dynamic> json) - : isImport = _createValue(json['isImport']), - isDeferred = _createValue(json['isDeferred']), - prefix = _createValue(json['prefix']), - targetId = _createValue(json['targetId']); + : isImport = _createValue(json['isImport']), + isDeferred = _createValue(json['isDeferred']), + prefix = _createValue(json['prefix']), + targetId = _createValue(json['targetId']); @override Map<String, dynamic> toJson() => { - 'isImport': isImport, - 'isDeferred': isDeferred, - if (prefix != null) 'prefix': prefix, - 'targetId': targetId, - }; + 'isImport': isImport, + 'isDeferred': isDeferred, + if (prefix != null) 'prefix': prefix, + 'targetId': targetId, + }; } class Script implements SymbolTableElement { @@ -575,23 +582,19 @@ String get id => '$libraryId|$localId'; - Script({ - required this.uri, - required this.localId, - required this.libraryId, - }); + Script({required this.uri, required this.localId, required this.libraryId}); Script.fromJson(Map<String, dynamic> json) - : uri = _createValue(json['uri']), - localId = _createValue(json['localId']), - libraryId = _createValue(json['libraryId']); + : uri = _createValue(json['uri']), + localId = _createValue(json['localId']), + libraryId = _createValue(json['libraryId']); @override Map<String, dynamic> toJson() => { - 'uri': uri, - 'localId': localId, - 'libraryId': libraryId, - }; + 'uri': uri, + 'localId': localId, + 'libraryId': libraryId, + }; } class ScopeSymbol extends Symbol { @@ -609,20 +612,20 @@ required super.localId, super.scopeId, super.location, - }) : variableIds = variableIds ?? [], - scopeIds = scopeIds ?? []; + }) : variableIds = variableIds ?? [], + scopeIds = scopeIds ?? []; ScopeSymbol.fromJson(super.json) - : variableIds = _createValueList(json['variableIds']), - scopeIds = _createValueList(json['scopeIds']), - super.fromJson(); + : variableIds = _createValueList(json['variableIds']), + scopeIds = _createValueList(json['scopeIds']), + super.fromJson(); @override Map<String, dynamic> toJson() => { - ...super.toJson(), - if (variableIds.isNotEmpty) 'variableIds': variableIds, - if (scopeIds.isNotEmpty) 'scopeIds': scopeIds, - }; + ...super.toJson(), + if (variableIds.isNotEmpty) 'variableIds': variableIds, + if (scopeIds.isNotEmpty) 'scopeIds': scopeIds, + }; } class SourceLocation implements SymbolTableElement { @@ -642,20 +645,22 @@ }); SourceLocation.fromJson(Map<String, dynamic> json) - : scriptId = _createValue(json['scriptId']), - tokenPos = _createValue(json['tokenPos']), - endTokenPos = _createValue(json['endTokenPos']); + : scriptId = _createValue(json['scriptId']), + tokenPos = _createValue(json['tokenPos']), + endTokenPos = _createValue(json['endTokenPos']); @override Map<String, dynamic> toJson() => { - 'scriptId': scriptId, - 'tokenPos': tokenPos, - if (endTokenPos != null) 'endTokenPos': endTokenPos, - }; + 'scriptId': scriptId, + 'tokenPos': tokenPos, + if (endTokenPos != null) 'endTokenPos': endTokenPos, + }; } List<T> _createObjectList<T>( - dynamic json, T Function(Map<String, dynamic>) creator) { + dynamic json, + T Function(Map<String, dynamic>) creator, +) { if (json == null) return <T>[]; if (json is List) { return json.map((e) => _createObject(e, creator)).toList(); @@ -671,11 +676,15 @@ } T? _createNullableObject<T>( - dynamic json, T Function(Map<String, dynamic>) creator) => - json == null ? null : _createObject(json, creator); + dynamic json, + T Function(Map<String, dynamic>) creator, +) => json == null ? null : _createObject(json, creator); -List<T> _createValueList<T>(dynamic json, - {T? ifNull, T Function(String)? parse}) { +List<T> _createValueList<T>( + dynamic json, { + T? ifNull, + T Function(String)? parse, +}) { if (json == null) return <T>[]; if (json is List) { return json @@ -702,13 +711,19 @@ } void _setObjectListIfNotNullOrEmpty<T extends SymbolTableElement>( - Map<String, dynamic> json, String key, List<T>? values) { + Map<String, dynamic> json, + String key, + List<T>? values, +) { if (values == null || values.isEmpty) return; json[key] = values.map((e) => e.toJson()).toList(); } void _setObjectIfNotNull<T extends SymbolTableElement>( - Map<String, dynamic> json, String key, T? value) { + Map<String, dynamic> json, + String key, + T? value, +) { if (value == null) return; json[key] = value.toJson(); }
diff --git a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart index 0e64d10..eea2bfa 100644 --- a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart +++ b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
@@ -21,9 +21,13 @@ final Map<Procedure, String> _procedureJsNames; final Map<VariableDeclaration, String> _variableJsNames; - ModuleSymbolsCollector(String moduleName, this._classJsNames, - this._memberJsNames, this._procedureJsNames, this._variableJsNames) - : _moduleSymbols = ModuleSymbols(moduleName: moduleName); + ModuleSymbolsCollector( + String moduleName, + this._classJsNames, + this._memberJsNames, + this._procedureJsNames, + this._variableJsNames, + ) : _moduleSymbols = ModuleSymbols(moduleName: moduleName); ModuleSymbols collectSymbolInfo(Component node) { node.accept(this); @@ -43,19 +47,21 @@ /// Returns the symbol for the function defined by [node]. void _createFunctionSymbol(Member node) { var functionSymbol = FunctionSymbol( - name: node.name.text, - // TODO(nshahan) typeId - probably should canonicalize but keep original - // type argument names. - typeId: null, - // TODO(nshahan) Should we mark all constructors static? - isStatic: node is Procedure ? node.isStatic : false, - isConst: node.isConst, - localId: _memberJsNames[node] ?? _procedureJsNames[node]!, - scopeId: _scopes.last.id, - location: SourceLocation( - scriptId: _scriptId(node.location!.file), - tokenPos: node.fileOffset, - endTokenPos: node.fileEndOffset)); + name: node.name.text, + // TODO(nshahan) typeId - probably should canonicalize but keep original + // type argument names. + typeId: null, + // TODO(nshahan) Should we mark all constructors static? + isStatic: node is Procedure ? node.isStatic : false, + isConst: node.isConst, + localId: _memberJsNames[node] ?? _procedureJsNames[node]!, + scopeId: _scopes.last.id, + location: SourceLocation( + scriptId: _scriptId(node.location!.file), + tokenPos: node.fileOffset, + endTokenPos: node.fileEndOffset, + ), + ); _scopes.add(functionSymbol); node.visitChildren(this); @@ -70,25 +76,27 @@ // Some class names are not emitted, i.e. mixin applications. if (_classJsNames[node] != null) { var classSymbol = ClassSymbol( - name: node.name, - isAbstract: node.isAbstract, - isConst: node.constructors.any((constructor) => constructor.isConst), - superClassId: _classJsNames[node.superclass], - interfaceIds: [ - for (var type in node.implementedTypes) - _classJsNames[type.classNode]! - ], - typeParameters: { - for (var param in node.typeParameters) - // TODO(nshahan) Value should be the JS name. - param.name!: param.name! - }, - localId: _classJsNames[node]!, - scopeId: _scopes.last.id, - location: SourceLocation( - scriptId: _scriptId(node.location!.file), - tokenPos: node.startFileOffset, - endTokenPos: node.fileEndOffset)); + name: node.name, + isAbstract: node.isAbstract, + isConst: node.constructors.any((constructor) => constructor.isConst), + superClassId: _classJsNames[node.superclass], + interfaceIds: [ + for (var type in node.implementedTypes) + _classJsNames[type.classNode]!, + ], + typeParameters: { + for (var param in node.typeParameters) + // TODO(nshahan) Value should be the JS name. + param.name!: param.name!, + }, + localId: _classJsNames[node]!, + scopeId: _scopes.last.id, + location: SourceLocation( + scriptId: _scriptId(node.location!.file), + tokenPos: node.startFileOffset, + endTokenPos: node.fileEndOffset, + ), + ); _scopes.add(classSymbol); node.visitChildren(this); @@ -105,20 +113,22 @@ @override void visitField(Field node) { var fieldSymbol = VariableSymbol( - name: node.name.text, - kind: node.parent is Class - ? VariableSymbolKind.field - : VariableSymbolKind.global, - isConst: node.isConst, - isFinal: node.isFinal, - isStatic: node.isStatic, - typeId: _typeId(node.type), - localId: _memberJsNames[node]!, - scopeId: _scopes.last.id, - location: SourceLocation( - scriptId: _scriptId(node.location!.file), - tokenPos: node.fileOffset, - endTokenPos: node.fileEndOffset)); + name: node.name.text, + kind: node.parent is Class + ? VariableSymbolKind.field + : VariableSymbolKind.global, + isConst: node.isConst, + isFinal: node.isFinal, + isStatic: node.isStatic, + typeId: _typeId(node.type), + localId: _memberJsNames[node]!, + scopeId: _scopes.last.id, + location: SourceLocation( + scriptId: _scriptId(node.location!.file), + tokenPos: node.fileOffset, + endTokenPos: node.fileEndOffset, + ), + ); node.visitChildren(this); _scopes.last.variableIds.add(fieldSymbol.id); _moduleSymbols.variables.add(fieldSymbol); @@ -132,10 +142,11 @@ dependencies: [ for (var dep in node.dependencies) LibrarySymbolDependency( - isImport: dep.isImport, - isDeferred: dep.isDeferred, - // TODO(nshahan) Need to handle prefixes. - targetId: dep.targetLibrary.importUri.toString()) + isImport: dep.isImport, + isDeferred: dep.isDeferred, + // TODO(nshahan) Need to handle prefixes. + targetId: dep.targetLibrary.importUri.toString(), + ), ], scriptIds: [], ); @@ -143,14 +154,16 @@ // TODO(nshahan) Save some space by using integers as local ids? var scripts = [ Script( - uri: node.fileUri.toString(), - localId: _scriptId(node.fileUri), - libraryId: librarySymbol.id), + uri: node.fileUri.toString(), + localId: _scriptId(node.fileUri), + libraryId: librarySymbol.id, + ), for (var part in node.parts) Script( - uri: node.fileUri.resolve(part.partUri).toString(), - localId: _scriptId(node.fileUri.resolve(part.partUri)), - libraryId: librarySymbol.id), + uri: node.fileUri.resolve(part.partUri).toString(), + localId: _scriptId(node.fileUri.resolve(part.partUri)), + libraryId: librarySymbol.id, + ), ]; librarySymbol.scriptIds.addAll(scripts.map((s) => s.id)); @@ -185,18 +198,21 @@ } VariableSymbol _createVariableSymbol( - VariableDeclaration node, VariableSymbolKind kind) => - VariableSymbol( - name: node.name!, - kind: kind, - isConst: node.isConst, - isFinal: node.isFinal, - // Static fields are visited in `visitField()`. - isStatic: false, - typeId: _typeId(node.type), - localId: _variableJsNames[node]!, - scopeId: _scopes.last.id, - location: SourceLocation( - scriptId: _scriptId(node.location!.file), - tokenPos: node.fileOffset)); + VariableDeclaration node, + VariableSymbolKind kind, + ) => VariableSymbol( + name: node.name!, + kind: kind, + isConst: node.isConst, + isFinal: node.isFinal, + // Static fields are visited in `visitField()`. + isStatic: false, + typeId: _typeId(node.type), + localId: _variableJsNames[node]!, + scopeId: _scopes.last.id, + location: SourceLocation( + scriptId: _scriptId(node.location!.file), + tokenPos: node.fileOffset, + ), + ); }
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart index 9705590..30ef95e 100644 --- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart +++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -43,7 +43,7 @@ final _variableInference = _NullableVariableInference(); NullableInference(this.jsTypeRep, this._staticTypeContext, {Options? options}) - : coreTypes = jsTypeRep.coreTypes { + : coreTypes = jsTypeRep.coreTypes { _variableInference._nullInference = this; } @@ -126,12 +126,20 @@ @override bool visitInstanceInvocation(InstanceInvocation node) => _invocationIsNullable( - node.interfaceTarget, node.name.text, node, node.receiver); + node.interfaceTarget, + node.name.text, + node, + node.receiver, + ); @override bool visitInstanceGetterInvocation(InstanceGetterInvocation node) => _invocationIsNullable( - node.interfaceTarget, node.name.text, node, node.receiver); + node.interfaceTarget, + node.name.text, + node, + node.receiver, + ); @override bool visitDynamicInvocation(DynamicInvocation node) => @@ -156,8 +164,11 @@ _invocationIsNullable(node.interfaceTarget, node.name.text, node); bool _invocationIsNullable( - Member? target, String name, InvocationExpression node, - [Expression? receiver]) { + Member? target, + String name, + InvocationExpression node, [ + Expression? receiver, + ]) { // TODO(jmesserly): this is not a valid assumption for user-defined equality // but it is added to match the behavior of the Analyzer backend. // https://github.com/dart-lang/sdk/issues/31854 @@ -191,11 +202,14 @@ // implementation class in dart:_interceptors, for example `JSString`. // // This allows us to find the `@notNull` annotation if it exists. - var implClass = jsTypeRep - .getImplementationClass(coreTypes.nonNullableRawType(targetClass)); + var implClass = jsTypeRep.getImplementationClass( + coreTypes.nonNullableRawType(targetClass), + ); if (implClass != null) { - var member = - jsTypeRep.hierarchy.getDispatchTarget(implClass, target.name); + var member = jsTypeRep.hierarchy.getDispatchTarget( + implClass, + target.name, + ); if (member != null) target = member; } } @@ -250,8 +264,8 @@ @override bool visitAsExpression(AsExpression node) => _staticallyNonNullable(node.getStaticType(_staticTypeContext)) - ? false - : isNullable(node.operand); + ? false + : isNullable(node.operand); @override bool visitSymbolLiteral(SymbolLiteral node) => false; @@ -305,7 +319,10 @@ _isInternalAnnotationField(value, 'nullCheck', '_NullCheck'); bool _isInternalAnnotationField( - Expression node, String fieldName, String className) { + Expression node, + String fieldName, + String className, + ) { if (node is ConstantExpression) { var constant = node.constant; return constant is InstanceConstant &&
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart index 99666b4..493bca3b 100644 --- a/pkg/dev_compiler/lib/src/kernel/property_model.dart +++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -76,8 +76,9 @@ // The set of public types is our initial extensible type set. // From there, visit all immediate private types in this library, and so on // from those private types, marking them as extensible. - var classesToVisit = - Queue<Class>.from(allClasses.where((c) => !c.name.startsWith('_'))); + var classesToVisit = Queue<Class>.from( + allClasses.where((c) => !c.name.startsWith('_')), + ); while (classesToVisit.isNotEmpty) { var c = classesToVisit.removeFirst(); @@ -100,11 +101,15 @@ Map<String, Field> getInstanceFieldMap(Class c) { var instanceFields = c.fields.where((f) => !f.isStatic); return HashMap.fromIterables( - instanceFields.map((f) => f.name.text), instanceFields); + instanceFields.map((f) => f.name.text), + instanceFields, + ); } - var allFields = - HashMap.fromIterables(allClasses, allClasses.map(getInstanceFieldMap)); + var allFields = HashMap.fromIterables( + allClasses, + allClasses.map(getInstanceFieldMap), + ); for (var class_ in allClasses) { Set<Class>? superclasses; @@ -145,8 +150,9 @@ // Look in all super classes to see if we're overriding a field in our // library, if so mark that field as overridden. var name = member.name.text; - _overriddenPrivateFields - .addAll(superclasses.map((c) => allFields[c]![name]).nonNulls); + _overriddenPrivateFields.addAll( + superclasses.map((c) => allFields[c]![name]).nonNulls, + ); } } } @@ -215,8 +221,12 @@ final extensionAccessors = <String>{}; - ClassPropertyModel.build(this.types, this.extensionTypes, - VirtualFieldModel fieldModel, Class class_) { + ClassPropertyModel.build( + this.types, + this.extensionTypes, + VirtualFieldModel fieldModel, + Class class_, + ) { // Visit superclasses to collect information about their fields/accessors. // This is expensive so we try to collect everything in one pass. var superclasses = [class_, ...getSuperclasses(class_)]; @@ -336,7 +346,10 @@ /// By tracking the set of seen members, we can visit superclasses and mixins /// and ultimately collect every most-derived member exposed by a given type. void _findExtensionMembers( - Class c, HashSet<String> seenConcreteMembers, Set<String> allNatives) { + Class c, + HashSet<String> seenConcreteMembers, + Set<String> allNatives, + ) { // We only visit each most derived concrete member. // To avoid visiting an overridden superclass member, we skip members // we've seen, and visit starting from the class, then mixins in
diff --git a/pkg/dev_compiler/lib/src/kernel/retry_timeout_client.dart b/pkg/dev_compiler/lib/src/kernel/retry_timeout_client.dart index 1cd5d7f..e2d58c3 100644 --- a/pkg/dev_compiler/lib/src/kernel/retry_timeout_client.dart +++ b/pkg/dev_compiler/lib/src/kernel/retry_timeout_client.dart
@@ -43,13 +43,13 @@ Duration Function(int retryCount)? connectionTimeout, Duration Function(int retryCount)? responseTimeout, void Function(Uri, HttpClientResponse?, int retryCount)? onRetry, - }) : _retries = retries, - _when = when ?? _defaultWhen, - _whenError = whenError ?? _defaultWhenError, - _delay = delay ?? _defaultDelay, - _connectionTimeout = connectionTimeout ?? _defaultTimeout, - _responseTimeout = responseTimeout ?? _defaultTimeout, - _onRetry = onRetry { + }) : _retries = retries, + _when = when ?? _defaultWhen, + _whenError = whenError ?? _defaultWhenError, + _delay = delay ?? _defaultDelay, + _connectionTimeout = connectionTimeout ?? _defaultTimeout, + _responseTimeout = responseTimeout ?? _defaultTimeout, + _onRetry = onRetry { RangeError.checkNotNegative(_retries, 'retries'); } @@ -62,7 +62,9 @@ } Future<HttpClientResponse> _retry( - Uri url, Future<HttpClientRequest> Function(Uri) method) async { + Uri url, + Future<HttpClientRequest> Function(Uri) method, + ) async { var i = 0; for (;;) { HttpClientResponse? response;
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart index f11231a..b45b620 100644 --- a/pkg/dev_compiler/lib/src/kernel/target.dart +++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -56,68 +56,68 @@ @override List<String> get extraRequiredLibraries => const [ - 'dart:_ddc_only', - 'dart:_runtime', - 'dart:_async_status_codes', - 'dart:_js_shared_embedded_names', - 'dart:_recipe_syntax', - 'dart:_rti', - 'dart:_debugger', - 'dart:_foreign_helper', - 'dart:_interceptors', - 'dart:_internal', - 'dart:_isolate_helper', - 'dart:_js_annotations', - 'dart:_js_helper', - 'dart:_js_names', - 'dart:_js_primitives', - 'dart:_js_types', - 'dart:_metadata', - 'dart:_native_typed_data', - 'dart:async', - 'dart:collection', - 'dart:convert', - 'dart:developer', - 'dart:io', - 'dart:isolate', - 'dart:js', - 'dart:js_interop', - 'dart:js_interop_unsafe', - 'dart:js_util', - 'dart:math', - 'dart:typed_data', - 'dart:indexed_db', - 'dart:html', - 'dart:html_common', - 'dart:svg', - 'dart:web_audio', - 'dart:web_gl', - ]; + 'dart:_ddc_only', + 'dart:_runtime', + 'dart:_async_status_codes', + 'dart:_js_shared_embedded_names', + 'dart:_recipe_syntax', + 'dart:_rti', + 'dart:_debugger', + 'dart:_foreign_helper', + 'dart:_interceptors', + 'dart:_internal', + 'dart:_isolate_helper', + 'dart:_js_annotations', + 'dart:_js_helper', + 'dart:_js_names', + 'dart:_js_primitives', + 'dart:_js_types', + 'dart:_metadata', + 'dart:_native_typed_data', + 'dart:async', + 'dart:collection', + 'dart:convert', + 'dart:developer', + 'dart:io', + 'dart:isolate', + 'dart:js', + 'dart:js_interop', + 'dart:js_interop_unsafe', + 'dart:js_util', + 'dart:math', + 'dart:typed_data', + 'dart:indexed_db', + 'dart:html', + 'dart:html_common', + 'dart:svg', + 'dart:web_audio', + 'dart:web_gl', + ]; // The libraries required to be indexed via CoreTypes. @override List<String> get extraIndexedLibraries => const [ - 'dart:async', - 'dart:collection', - 'dart:html', - 'dart:indexed_db', - 'dart:js', - 'dart:js_util', - 'dart:js_interop', - 'dart:js_interop_unsafe', - 'dart:math', - 'dart:svg', - 'dart:typed_data', - 'dart:web_audio', - 'dart:web_gl', - 'dart:_foreign_helper', - 'dart:_interceptors', - 'dart:_js_helper', - 'dart:_js_types', - 'dart:_native_typed_data', - 'dart:_runtime', - 'dart:_rti', - ]; + 'dart:async', + 'dart:collection', + 'dart:html', + 'dart:indexed_db', + 'dart:js', + 'dart:js_util', + 'dart:js_interop', + 'dart:js_interop_unsafe', + 'dart:math', + 'dart:svg', + 'dart:typed_data', + 'dart:web_audio', + 'dart:web_gl', + 'dart:_foreign_helper', + 'dart:_interceptors', + 'dart:_js_helper', + 'dart:_js_types', + 'dart:_native_typed_data', + 'dart:_runtime', + 'dart:_rti', + ]; @override bool mayDefineRestrictedType(Uri uri) => @@ -167,15 +167,16 @@ @override void performModularTransformationsOnLibraries( - Component component, - CoreTypes coreTypes, - ClassHierarchy hierarchy, - List<Library> libraries, - Map<String, String>? environmentDefines, - DiagnosticReporter diagnosticReporter, - ReferenceFromIndex? referenceFromIndex, - {void Function(String msg)? logger, - ChangedStructureNotifier? changedStructureNotifier}) { + Component component, + CoreTypes coreTypes, + ClassHierarchy hierarchy, + List<Library> libraries, + Map<String, String>? environmentDefines, + DiagnosticReporter diagnosticReporter, + ReferenceFromIndex? referenceFromIndex, { + void Function(String msg)? logger, + ChangedStructureNotifier? changedStructureNotifier, + }) { _nativeClasses ??= JsInteropChecks.getNativeClasses(component); _diagnosticReporter = diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>; @@ -184,11 +185,12 @@ @override void performTransformationsOnProcedure( - CoreTypes coreTypes, - ClassHierarchy hierarchy, - Procedure procedure, - Map<String, String>? environmentDefines, - {void Function(String)? logger}) { + CoreTypes coreTypes, + ClassHierarchy hierarchy, + Procedure procedure, + Map<String, String>? environmentDefines, { + void Function(String)? logger, + }) { _performTransformations(coreTypes, hierarchy, [procedure]); } @@ -199,19 +201,27 @@ ) { final jsInteropReporter = JsInteropDiagnosticReporter(_diagnosticReporter!); final jsInteropChecks = JsInteropChecks( - coreTypes, hierarchy, jsInteropReporter, _nativeClasses!); + coreTypes, + hierarchy, + jsInteropReporter, + _nativeClasses!, + ); for (var node in nodes) { // Process and validate first before doing anything with exports. node.accept(jsInteropChecks); } final sharedInteropTransformer = SharedInteropTransformer( - TypeEnvironment(coreTypes, hierarchy), - jsInteropReporter, - jsInteropChecks.exportChecker, - jsInteropChecks.extensionIndex); + TypeEnvironment(coreTypes, hierarchy), + jsInteropReporter, + jsInteropChecks.exportChecker, + jsInteropChecks.extensionIndex, + ); final jsUtilOptimizer = JsUtilOptimizer( - coreTypes, hierarchy, jsInteropChecks.extensionIndex, - isDart2JS: false); + coreTypes, + hierarchy, + jsInteropChecks.extensionIndex, + isDart2JS: false, + ); for (var node in nodes) { _CovarianceTransformer(node).transform(); // Shared interop transformer has static checks, so we still visit. @@ -225,12 +235,13 @@ @override void performPreConstantEvaluationTransformations( - Component component, - CoreTypes coreTypes, - List<Library> libraries, - DiagnosticReporter diagnosticReporter, - {void Function(String msg)? logger, - ChangedStructureNotifier? changedStructureNotifier}) { + Component component, + CoreTypes coreTypes, + List<Library> libraries, + DiagnosticReporter diagnosticReporter, { + void Function(String msg)? logger, + ChangedStructureNotifier? changedStructureNotifier, + }) { if (flags.trackWidgetCreation) { _widgetTracker ??= WidgetCreatorTracker(); _widgetTracker!.transform(component, libraries, changedStructureNotifier); @@ -238,8 +249,14 @@ } @override - Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver, - String name, Arguments arguments, int offset, bool isSuper) { + Expression instantiateInvocation( + CoreTypes coreTypes, + Expression receiver, + String name, + Arguments arguments, + int offset, + bool isSuper, + ) { // TODO(jmesserly): preserve source information? // (These method are synthetic. Also unclear if the offset will correspond // to the file where the class resides, or the file where the method we're @@ -260,8 +277,10 @@ return createInvocation('getter', [SymbolLiteral(name.substring(4))]); } if (name.startsWith('set:')) { - return createInvocation('setter', - [SymbolLiteral(name.substring(4)), arguments.positional.single]); + return createInvocation('setter', [ + SymbolLiteral(name.substring(4)), + arguments.positional.single, + ]); } var ctorArgs = <Expression>[ SymbolLiteral(name), @@ -273,7 +292,7 @@ if (arguments.named.isNotEmpty) MapLiteral([ for (var n in arguments.named) - MapLiteralEntry(SymbolLiteral(n.name), n.value) + MapLiteralEntry(SymbolLiteral(n.name), n.value), ], keyType: coreTypes.symbolNonNullableRawType) else NullLiteral(), @@ -282,18 +301,23 @@ } @override - Expression instantiateNoSuchMethodError(CoreTypes coreTypes, - Expression receiver, String name, Arguments arguments, int offset, - {bool isMethod = false, - bool isGetter = false, - bool isSetter = false, - bool isField = false, - bool isLocalVariable = false, - bool isDynamic = false, - bool isSuper = false, - bool isStatic = false, - bool isConstructor = false, - bool isTopLevel = false}) { + Expression instantiateNoSuchMethodError( + CoreTypes coreTypes, + Expression receiver, + String name, + Arguments arguments, + int offset, { + bool isMethod = false, + bool isGetter = false, + bool isSetter = false, + bool isField = false, + bool isLocalVariable = false, + bool isDynamic = false, + bool isSuper = false, + bool isStatic = false, + bool isConstructor = false, + bool isTopLevel = false, + }) { // TODO(sigmund): implement; return InvalidExpression(null); } @@ -431,8 +455,10 @@ target.isInstanceMember && receiver is! ThisExpression && receiver is! ConstructorInvocation) { - assert(target.enclosingLibrary == _library, - 'call to private member must be in same library'); + assert( + target.enclosingLibrary == _library, + 'call to private member must be in same library', + ); _checkedMembers.add(target); } } @@ -449,8 +475,10 @@ target.isInstanceMember && target is Procedure && !target.isAccessor) { - assert(target.enclosingLibrary == _library, - 'tearoff of private member must be in same library'); + assert( + target.enclosingLibrary == _library, + 'tearoff of private member must be in same library', + ); _checkedMembers.add(target); } }
diff --git a/pkg/dev_compiler/lib/src/kernel/type_environment.dart b/pkg/dev_compiler/lib/src/kernel/type_environment.dart index 8636376..2cc3aa7 100644 --- a/pkg/dev_compiler/lib/src/kernel/type_environment.dart +++ b/pkg/dev_compiler/lib/src/kernel/type_environment.dart
@@ -181,7 +181,7 @@ : BindingTypeEnvironment([ // Place new parameters first so they can effectively shadow // parameters already in the environment. - ...parameters, ..._typeParameters + ...parameters, ..._typeParameters, ]); } @@ -235,16 +235,18 @@ : ExtendedTypeEnvironment(_baseTypeEnvironment, [ // Place new parameters first so they can effectively shadow // parameters already in the environment. - ...parameters, ..._typeParameters + ...parameters, ..._typeParameters, ]); } @override DDCTypeEnvironment prune(Iterable<TypeParameter> requiredParameters) { - var baseEnvironmentNeeded = - requiredParameters.any(_baseTypeEnvironment._typeParameters.contains); - var additionalParameters = - requiredParameters.where(_typeParameters.contains); + var baseEnvironmentNeeded = requiredParameters.any( + _baseTypeEnvironment._typeParameters.contains, + ); + var additionalParameters = requiredParameters.where( + _typeParameters.contains, + ); if (additionalParameters.isEmpty) { return baseEnvironmentNeeded // Simply using the base environment has a compact representation @@ -257,7 +259,9 @@ if (additionalParameters.length == _typeParameters.length) return this; // An extended environment with fewer additional parameters is needed. return ExtendedTypeEnvironment( - _baseTypeEnvironment, additionalParameters.toList()); + _baseTypeEnvironment, + additionalParameters.toList(), + ); } @override
diff --git a/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart b/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart index 7745ae1..47aba39 100644 --- a/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart +++ b/pkg/dev_compiler/lib/src/kernel/type_recipe_generator.dart
@@ -32,10 +32,12 @@ final FutureOrNormalizer _futureOrNormalizer; TypeRecipeGenerator(CoreTypes coreTypes, this._hierarchy) - : _coreTypes = coreTypes, - _recipeVisitor = - _TypeRecipeVisitor(const EmptyTypeEnvironment(), coreTypes), - _futureOrNormalizer = FutureOrNormalizer(coreTypes); + : _coreTypes = coreTypes, + _recipeVisitor = _TypeRecipeVisitor( + const EmptyTypeEnvironment(), + coreTypes, + ), + _futureOrNormalizer = FutureOrNormalizer(coreTypes); /// Returns a recipe for the provided [type] packaged with an environment with /// which to evaluate the recipe in. @@ -43,8 +45,10 @@ /// The returned environment will be a subset of the provided [environment] /// that includes only the necessary types to evaluate the recipe. GeneratedRecipe recipeInEnvironment( - DartType type, DDCTypeEnvironment environment, - {bool emitJSInteropGenericClassTypeParametersAsAny = true}) { + DartType type, + DDCTypeEnvironment environment, { + bool emitJSInteropGenericClassTypeParametersAsAny = true, + }) { // Reduce the provided environment down to the parameters that are present. var parametersInType = TypeParameterFinder.instance().find(type); var minimalEnvironment = environment.prune(parametersInType); @@ -74,9 +78,9 @@ /// Returns all recipes for [InterfaceType]s that have appeared in type /// recipes. List<String> get visitedInterfaceTypeRecipes => [ - for (var type in _recipeVisitor.visitedInterfaceTypes) - interfaceTypeRecipe(type.classNode) - ]; + for (var type in _recipeVisitor.visitedInterfaceTypes) + interfaceTypeRecipe(type.classNode), + ]; /// Returns a mapping of type hierarchies for all [InterfaceType]s that have /// appeared in type recipes. @@ -118,11 +122,12 @@ // added here. There is special redirecting rule logic in the dart:_rti // library for interop types because otherwise they would duplicate // a lot of supertype information. - var legacyJavaScriptObjectRecipe = interfaceTypeRecipe(_coreTypes.index - .getClass('dart:_interceptors', 'LegacyJavaScriptObject')); + var legacyJavaScriptObjectRecipe = interfaceTypeRecipe( + _coreTypes.index.getClass('dart:_interceptors', 'LegacyJavaScriptObject'), + ); var rules = <String, Object>{ for (var recipe in visitedJsInteropTypeRecipes) - recipe: legacyJavaScriptObjectRecipe + recipe: legacyJavaScriptObjectRecipe, }; // All Dart types hierarchy rules are generated by exploring their class @@ -133,11 +138,12 @@ // Create a class type environment for calculating type argument indices. // Avoid recording the types while iterating the visited types. _recipeVisitor.setState( - environment: ClassTypeEnvironment(cls.typeParameters), - // No need to add any more live types at this time. Any "new" types - // seen in this process are not live. - addLiveInterfaceTypes: false, - emitClassTypeParametersAsIndices: true); + environment: ClassTypeEnvironment(cls.typeParameters), + // No need to add any more live types at this time. Any "new" types + // seen in this process are not live. + addLiveInterfaceTypes: false, + emitClassTypeParametersAsIndices: true, + ); var supertypeEntries = <String, Object>{}; // Encode the type argument mapping portion of this type rule. for (var i = 0; i < cls.typeParameters.length; i++) { @@ -166,7 +172,7 @@ for (var typeArgument in currentType.typeArguments) _futureOrNormalizer .normalize(typeArgument.extensionTypeErasure) - .accept(_recipeVisitor) + .accept(_recipeVisitor), ]; // Encode the type argument mapping portion of this type rule. for (var i = 0; i < currentClass.typeParameters.length; i++) { @@ -197,8 +203,8 @@ when typeParameters.any((element) => !element.isLegacyCovariant)) interfaceTypeRecipe(cls): [ for (var typeParameter in typeParameters) - _convertVariance(typeParameter) - ] + _convertVariance(typeParameter), + ], }; } @@ -208,24 +214,28 @@ var recipes = visitedJsInteropTypeRecipes; return { if (recipes.isNotEmpty) - interfaceTypeRecipe(_coreTypes.index - .getClass('dart:_interceptors', 'LegacyJavaScriptObject')): - // Update type rules for `LegacyJavaScriptObject` to add all interop - // types in this module as a supertype. - { + interfaceTypeRecipe( + _coreTypes.index.getClass( + 'dart:_interceptors', + 'LegacyJavaScriptObject', + ), + ): + // Update type rules for `LegacyJavaScriptObject` to add all interop + // types in this module as a supertype. + { for (var interopType in _recipeVisitor._visitedJsInteropTypes) interfaceTypeRecipe(interopType.classNode): _recipeVisitor - ._listOfJSAnyType(interopType.typeArguments.length) - } + ._listOfJSAnyType(interopType.typeArguments.length), + }, }; } String interfaceTypeRecipe(Class node) => _recipeVisitor.interfaceTypeRecipe(node); - Iterable<String> get visitedJsInteropTypeRecipes => - _recipeVisitor.visitedJsInteropTypes - .map((type) => interfaceTypeRecipe(type.classNode)); + Iterable<String> get visitedJsInteropTypeRecipes => _recipeVisitor + .visitedJsInteropTypes + .map((type) => interfaceTypeRecipe(type.classNode)); /// Converts the AST variance of the [typeParameter] to one that can be used /// at runtime. @@ -237,8 +247,9 @@ Variance.covariant => shared_variance.Variance.covariant.index, Variance.contravariant => shared_variance.Variance.contravariant.index, Variance.invariant => shared_variance.Variance.invariant.index, - var variance => - throw UnsupportedError('Variance $variance is not supported.'), + var variance => throw UnsupportedError( + 'Variance $variance is not supported.', + ), }; } } @@ -346,15 +357,18 @@ String visitInterfaceType(InterfaceType node) { var cls = node.classNode; if (isStaticInteropType(cls)) { - return eraseStaticInteropTypesForJSCompilers(_coreTypes, node) - .accept(this); + return eraseStaticInteropTypesForJSCompilers( + _coreTypes, + node, + ).accept(this); } addLiveTypeAncestries(node); // Generate the interface type recipe. var recipeBuffer = StringBuffer(interfaceTypeRecipe(cls)); // Generate the recipes for all type arguments. if (node.typeArguments.isNotEmpty) { - var argumentRecipes = _emitJSInteropGenericClassTypeParametersAsAny && + var argumentRecipes = + _emitJSInteropGenericClassTypeParametersAsAny && hasJSInteropAnnotation(cls) ? _listOfJSAnyType(node.typeArguments.length) : node.typeArguments.map((typeArgument) => typeArgument.accept(this)); @@ -383,7 +397,7 @@ // parameter types and uses them in the parameter and return types. _unboundTypeParameters = [ for (var parameter in node.typeParameters) parameter.name!, - ..._unboundTypeParameters + ..._unboundTypeParameters, ]; // Generate the return type recipe. var recipeBuffer = StringBuffer(node.returnType.accept(this)); @@ -418,9 +432,11 @@ for (var i = 0; i < namedCount; i++) { var named = namedParameters[i]; recipeBuffer.write(named.name); - recipeBuffer.write(named.isRequired - ? Recipe.requiredNameSeparatorString - : Recipe.nameSeparatorString); + recipeBuffer.write( + named.isRequired + ? Recipe.requiredNameSeparatorString + : Recipe.nameSeparatorString, + ); recipeBuffer.write(named.type.accept(this)); if (i < namedCount - 1) { recipeBuffer.write(Recipe.separatorString); @@ -434,8 +450,9 @@ if (typeParameters.isNotEmpty) { recipeBuffer.write(Recipe.startTypeArgumentsString); recipeBuffer.writeAll( - typeParameters.map((parameter) => parameter.bound.accept(this)), - Recipe.separatorString); + typeParameters.map((parameter) => parameter.bound.accept(this)), + Recipe.separatorString, + ); recipeBuffer.write(Recipe.endTypeArgumentsString); } _unboundTypeParameters = savedUnboundTypeParameters; @@ -453,15 +470,19 @@ var recipeBuffer = StringBuffer(Recipe.startRecordString); // Add the names of the named elements. recipeBuffer.writeAll( - node.named.map((element) => element.name), Recipe.separatorString); + node.named.map((element) => element.name), + Recipe.separatorString, + ); // Add all element types. recipeBuffer.write(Recipe.startFunctionArgumentsString); var elementTypes = [ ...node.positional, - ...node.named.map((element) => element.type) + ...node.named.map((element) => element.type), ]; - recipeBuffer.writeAll(elementTypes.map((element) => element.accept(this)), - Recipe.separatorString); + recipeBuffer.writeAll( + elementTypes.map((element) => element.accept(this)), + Recipe.separatorString, + ); recipeBuffer.write(Recipe.endFunctionArgumentsString); // Add the records nullability. recipeBuffer.write(_nullabilityRecipe(node)); @@ -480,8 +501,8 @@ if (!_emitClassTypeParametersAsIndices && parameterDeclaration is Class) { // Generic type parameters in binding positions will still be emitted // with indices. - var typeParamInBindingPosition = _typeEnvironment - is BindingTypeEnvironment || + var typeParamInBindingPosition = + _typeEnvironment is BindingTypeEnvironment || (_typeEnvironment is ExtendedTypeEnvironment && _typeEnvironment.functionTypeParameters.contains(node.parameter)); if (!typeParamInBindingPosition) { @@ -499,9 +520,10 @@ i = _typeEnvironment.recipeIndexOf(node.parameter); if (i < 0) { throw UnsupportedError( - 'Type parameter $node was not found in the environment ' - '$_typeEnvironment or in the unbound parameters ' - '$_unboundTypeParameters.'); + 'Type parameter $node was not found in the environment ' + '$_typeEnvironment or in the unbound parameters ' + '$_unboundTypeParameters.', + ); } return '$i${_nullabilityRecipe(node)}'; } @@ -519,8 +541,9 @@ '${_nullabilityRecipe(node)}'; } else { throw UnsupportedError( - 'Type parameter $node was not found in the unbound parameters ' - '$_unboundTypeParameters.'); + 'Type parameter $node was not found in the unbound parameters ' + '$_unboundTypeParameters.', + ); } } @@ -528,10 +551,10 @@ String visitNeverType(NeverType node) => // Normalize Never? -> Null node.nullability == Nullability.nullable - ? visitNullType(const NullType()) - : '${Recipe.pushNeverExtensionString}' - '${Recipe.extensionOpString}' - '${_nullabilityRecipe(node)}'; + ? visitNullType(const NullType()) + : '${Recipe.pushNeverExtensionString}' + '${Recipe.extensionOpString}' + '${_nullabilityRecipe(node)}'; @override String visitNullType(NullType node) => @@ -578,7 +601,9 @@ List<String> _listOfJSAnyType(int n) => n == 0 ? const [] : List.filled( - n, '${Recipe.pushAnyExtensionString}${Recipe.extensionOpString}'); + n, + '${Recipe.pushAnyExtensionString}${Recipe.extensionOpString}', + ); /// Manually record the transitive type ancestries of [type], and any other /// interface types that appear as instantiated type arguments within as being @@ -606,8 +631,10 @@ var currentClass = toVisit.removeFirst().classNode; // Avoid duplicates of an interface that differ only in nullability by // always working with the non-nullable version. - var currentType = - currentClass.getThisType(_coreTypes, Nullability.nonNullable); + var currentType = currentClass.getThisType( + _coreTypes, + Nullability.nonNullable, + ); if (_visitedInterfaceTypes.contains(currentType) || _visitedJsInteropTypes.contains(currentType) || currentClass == _coreTypes.objectClass) {
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart index 56a7c37..72942c1 100644 --- a/pkg/dev_compiler/lib/src/kernel/type_table.dart +++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -14,9 +14,10 @@ import 'kernel_helpers.dart'; /// Returns all non-locally defined type parameters referred to by [t]. -Set< /* TypeParameter | StructuralParameter */ Object> freeTypeParameters( - DartType t) { - var result = < /* TypeParameter | StructuralParameter */ Object>{}; +Set</* TypeParameter | StructuralParameter */ Object> freeTypeParameters( + DartType t, +) { + var result = </* TypeParameter | StructuralParameter */ Object>{}; void find(DartType t) { switch (t) { case TypeParameterType(): @@ -66,8 +67,8 @@ var nullability = type.declaredNullability == Nullability.legacy ? 'L' : type.declaredNullability == Nullability.nullable - ? 'N' - : ''; + ? 'N' + : ''; switch (type) { case InterfaceType(): var name = '${type.classNode.name}$nullability'; @@ -115,8 +116,9 @@ return 'Null'; case RecordType(): if (flat) return 'Rec'; - var positional = - type.positional.take(3).map((p) => _typeString(p, flat: true)); + var positional = type.positional + .take(3) + .map((p) => _typeString(p, flat: true)); var elements = positional.join('And'); if (type.positional.length > 3 || type.named.isNotEmpty) { elements = '${elements}__'; @@ -137,7 +139,7 @@ /// type variable since the type definition depends on the type /// parameter. final _scopeDependencies = - < /* TypeParameter | StructuralParameter */ Object, List<DartType>>{}; + </* TypeParameter | StructuralParameter */ Object, List<DartType>>{}; /// Contains types with any free type parameters and maps them to a unique /// JS identifier. @@ -152,8 +154,10 @@ final js_ast.Expression Function(String, [List<Object>]) _runtimeCall; TypeTable(String name, this._runtimeCall) - : typeContainer = ModuleItemContainer<DartType>.asObject(name, - keyToString: (DartType t) => escapeIdentifier(_typeString(t))); + : typeContainer = ModuleItemContainer<DartType>.asObject( + name, + keyToString: (DartType t) => escapeIdentifier(_typeString(t)), + ); /// Returns true if [type] is already recorded in the table. bool _isNamed(DartType type) => @@ -176,7 +180,7 @@ var access = js.call('#.#', [data.id, data.jsKey]); return js.call('() => ((# = #)())', [ access, - _runtimeCall('constFn(#)', [data.jsValue]) + _runtimeCall('constFn(#)', [data.jsValue]), ]); } @@ -197,7 +201,7 @@ return js.statement('var # = () => ((# = #)());', [ id, id, - _runtimeCall('constFn(#)', [init]) + _runtimeCall('constFn(#)', [init]), ]); } @@ -206,12 +210,16 @@ /// /// If [formals] is present, only emit the definitions which depend on the /// formals. - List<js_ast.Statement> dischargeFreeTypes( - [Iterable< /* TypeParameter | StructuralTypeParameter */ Object>? - formals]) { - assert(formals == null || - formals.every((parameter) => - parameter is TypeParameter || parameter is StructuralParameter)); + List<js_ast.Statement> dischargeFreeTypes([ + Iterable</* TypeParameter | StructuralTypeParameter */ Object>? formals, + ]) { + assert( + formals == null || + formals.every( + (parameter) => + parameter is TypeParameter || parameter is StructuralParameter, + ), + ); var decls = <js_ast.Statement>[]; var types = formals == null ? typeContainer.keys.where((p) => freeTypeParameters(p).isNotEmpty) @@ -251,9 +259,11 @@ // readability to little or no benefit. It would be good to do this // when we know that we can hoist it to an outer scope, but for // now we just disable it. - if (freeVariables.any((i) => - i is TypeParameter && i.declaration is GenericFunction || - i is StructuralParameter)) { + if (freeVariables.any( + (i) => + i is TypeParameter && i.declaration is GenericFunction || + i is StructuralParameter, + )) { return true; } @@ -266,8 +276,9 @@ if (freeVariables.isNotEmpty) { // TODO(40273) Remove prepended text when we have a better way to hide // these names from debug tools. - _unboundTypeIds[type] = - js_ast.ScopedId(escapeIdentifier('__t\$${_typeString(type)}')); + _unboundTypeIds[type] = js_ast.ScopedId( + escapeIdentifier('__t\$${_typeString(type)}'), + ); } for (var free in freeVariables) { @@ -296,8 +307,10 @@ /// type itself. This allows better integration with `lazyFn`, avoiding an /// extra level of indirection. js_ast.Expression nameFunctionType( - FunctionType type, js_ast.Expression typeRep, - {bool lazy = false}) { + FunctionType type, + js_ast.Expression typeRep, { + bool lazy = false, + }) { if (recordScopeDependencies(type)) { return lazy ? js_ast.ArrowFun([], typeRep) : typeRep; }
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml index c40b07a..9c82aea 100644 --- a/pkg/dev_compiler/pubspec.yaml +++ b/pkg/dev_compiler/pubspec.yaml
@@ -3,7 +3,7 @@ publish_to: none environment: - sdk: ^3.6.0 + sdk: ^3.8.0 resolution: workspace
diff --git a/pkg/dev_compiler/test/dynamic/dartdevc_dynamic_test.dart b/pkg/dev_compiler/test/dynamic/dartdevc_dynamic_test.dart index cc216ef..4f5937f 100644 --- a/pkg/dev_compiler/test/dynamic/dartdevc_dynamic_test.dart +++ b/pkg/dev_compiler/test/dynamic/dartdevc_dynamic_test.dart
@@ -7,36 +7,44 @@ import 'package:kernel/ast.dart'; Future<void> main(List<String> args) async { - await run(dartdevcEntryPoints, - 'pkg/dev_compiler/test/dynamic/dartdevc_allowed.json', - analyzedUrisFilter: dartdevcOnly, - verbose: args.contains('-v'), - generate: args.contains('-g')); + await run( + dartdevcEntryPoints, + 'pkg/dev_compiler/test/dynamic/dartdevc_allowed.json', + analyzedUrisFilter: dartdevcOnly, + verbose: args.contains('-v'), + generate: args.contains('-g'), + ); } -Future<void> run(List<Uri> entryPoints, String allowedListPath, - {bool verbose = false, - bool generate = false, - bool Function(Uri uri)? analyzedUrisFilter}) async { - await runAnalysis(entryPoints, - (DiagnosticMessageHandler onDiagnostic, Component component) { - DynamicVisitor(onDiagnostic, component, allowedListPath, analyzedUrisFilter) - .run(verbose: verbose, generate: generate); +Future<void> run( + List<Uri> entryPoints, + String allowedListPath, { + bool verbose = false, + bool generate = false, + bool Function(Uri uri)? analyzedUrisFilter, +}) async { + await runAnalysis(entryPoints, ( + DiagnosticMessageHandler onDiagnostic, + Component component, + ) { + DynamicVisitor( + onDiagnostic, + component, + allowedListPath, + analyzedUrisFilter, + ).run(verbose: verbose, generate: generate); }); } /// Entry points used for analyzing dartdevc code. final List<Uri> dartdevcEntryPoints = [ - Uri.base.resolve('pkg/dev_compiler/bin/dartdevc.dart') + Uri.base.resolve('pkg/dev_compiler/bin/dartdevc.dart'), ]; /// Filter function used to only analyze dartdevc source code. bool dartdevcOnly(Uri uri) { var text = '$uri'; - for (var path in [ - 'package:_js_interop_checks/', - 'package:dev_compiler/', - ]) { + for (var path in ['package:_js_interop_checks/', 'package:dev_compiler/']) { if (text.startsWith(path)) { return true; }
diff --git a/pkg/dev_compiler/test/dynamic/platform_dynamic_test.dart b/pkg/dev_compiler/test/dynamic/platform_dynamic_test.dart index 1f41421..217bc45 100644 --- a/pkg/dev_compiler/test/dynamic/platform_dynamic_test.dart +++ b/pkg/dev_compiler/test/dynamic/platform_dynamic_test.dart
@@ -9,15 +9,27 @@ import 'package:kernel/target/targets.dart'; Future<void> main(List<String> args) async { - await run('pkg/dev_compiler/test/dynamic/platform_allowed.json', - verbose: args.contains('-v'), generate: args.contains('-g')); + await run( + 'pkg/dev_compiler/test/dynamic/platform_allowed.json', + verbose: args.contains('-v'), + generate: args.contains('-g'), + ); } -Future<void> run(String allowedListPath, - {bool verbose = false, bool generate = false}) async { - await runPlatformAnalysis(DevCompilerTarget(TargetFlags()), - (DiagnosticMessageHandler onDiagnostic, Component component) { - DynamicVisitor(onDiagnostic, component, allowedListPath, platformOnly) - .run(verbose: verbose, generate: generate); +Future<void> run( + String allowedListPath, { + bool verbose = false, + bool generate = false, +}) async { + await runPlatformAnalysis(DevCompilerTarget(TargetFlags()), ( + DiagnosticMessageHandler onDiagnostic, + Component component, + ) { + DynamicVisitor( + onDiagnostic, + component, + allowedListPath, + platformOnly, + ).run(verbose: verbose, generate: generate); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/assertions_enabled_common.dart b/pkg/dev_compiler/test/expression_compiler/assertions_enabled_common.dart index 7c8325d..48d1199 100644 --- a/pkg/dev_compiler/test/expression_compiler/assertions_enabled_common.dart +++ b/pkg/dev_compiler/test/expression_compiler/assertions_enabled_common.dart
@@ -8,7 +8,9 @@ import 'expression_compiler_e2e_suite.dart'; void runTests( - ExpressionEvaluationTestDriver driver, SetupCompilerOptions setup) { + ExpressionEvaluationTestDriver driver, + SetupCompilerOptions setup, +) { group('Asserts', () { const source = r''' void main() { @@ -33,30 +35,35 @@ group('enabled |', () { test('dart.web.assertions_enabled is set', () async { await driver.checkInFrame( - breakpointId: 'bp', expression: 'b', expectedResult: 'true'); + breakpointId: 'bp', + expression: 'b', + expectedResult: 'true', + ); }); test('assert errors in the source code', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'myAssert()', - expectedError: allOf( - contains('Error: Assertion failed:'), - contains('test.dart:8:16'), - contains('false'), - contains('is not true'), - )); + breakpointId: 'bp', + expression: 'myAssert()', + expectedError: allOf( + contains('Error: Assertion failed:'), + contains('test.dart:8:16'), + contains('false'), + contains('is not true'), + ), + ); }); test('assert errors in evaluated expression', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: '() { assert(false); return 0; } ()', - expectedError: allOf( - contains('Error: Assertion failed:'), - contains('org-dartlang-debug:synthetic_debug_expression:1:13'), - contains('false'), - contains('is not true'), - )); + breakpointId: 'bp', + expression: '() { assert(false); return 0; } ()', + expectedError: allOf( + contains('Error: Assertion failed:'), + contains('org-dartlang-debug:synthetic_debug_expression:1:13'), + contains('false'), + contains('is not true'), + ), + ); }); }); } @@ -65,21 +72,26 @@ group('disabled |', () { test('dart.web.assertions_enabled is not set', () async { await driver.checkInFrame( - breakpointId: 'bp', expression: 'b', expectedResult: 'false'); + breakpointId: 'bp', + expression: 'b', + expectedResult: 'false', + ); }); test('no assert errors in the source code', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'myAssert()', - expectedResult: '0'); + breakpointId: 'bp', + expression: 'myAssert()', + expectedResult: '0', + ); }); test('no assert errors in evaluated expression', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: '() { assert(false); return 0; } ()', - expectedResult: '0'); + breakpointId: 'bp', + expression: '() { assert(false); return 0; } ()', + expectedResult: '0', + ); }); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/assertions_enabled_ddc_test.dart b/pkg/dev_compiler/test/expression_compiler/assertions_enabled_ddc_test.dart index 0846d10..dc64dec 100644 --- a/pkg/dev_compiler/test/expression_compiler/assertions_enabled_ddc_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/assertions_enabled_ddc_test.dart
@@ -13,7 +13,8 @@ final debug = false; final driver = await ExpressionEvaluationTestDriver.init(); runTests( - driver, - SetupCompilerOptions(moduleFormat: ModuleFormat.ddc, args: args) - ..options.verbose = debug); + driver, + SetupCompilerOptions(moduleFormat: ModuleFormat.ddc, args: args) + ..options.verbose = debug, + ); }
diff --git a/pkg/dev_compiler/test/expression_compiler/assertions_enabled_test.dart b/pkg/dev_compiler/test/expression_compiler/assertions_enabled_test.dart index 97cb5db..dc98428 100644 --- a/pkg/dev_compiler/test/expression_compiler/assertions_enabled_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/assertions_enabled_test.dart
@@ -13,7 +13,8 @@ final debug = false; final driver = await ExpressionEvaluationTestDriver.init(); runTests( - driver, - SetupCompilerOptions(moduleFormat: ModuleFormat.amd, args: args) - ..options.verbose = debug); + driver, + SetupCompilerOptions(moduleFormat: ModuleFormat.amd, args: args) + ..options.verbose = debug, + ); }
diff --git a/pkg/dev_compiler/test/expression_compiler/asset_file_system_test.dart b/pkg/dev_compiler/test/expression_compiler/asset_file_system_test.dart index 0280c9a..88c58cd 100644 --- a/pkg/dev_compiler/test/expression_compiler/asset_file_system_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/asset_file_system_test.dart
@@ -95,8 +95,11 @@ server = await HttpMultiServer.bind(hostname, port); fileSystem = AssetFileSystem.forTesting( - StandardFileSystem.instance, hostname, '$port', - retries: 0); + StandardFileSystem.instance, + hostname, + '$port', + retries: 0, + ); serveRequests(server, handler); }); @@ -134,7 +137,9 @@ test('cannot read non-existing file', () async { var entity = fileSystem.entityForUri(Uri.parse(_nonExistingFile)); await expectLater( - entity.readAsBytes(), throwsA(isA<FileSystemException>())); + entity.readAsBytes(), + throwsA(isA<FileSystemException>()), + ); }); test('can read a lot of files concurrently', () async { @@ -154,8 +159,11 @@ server = await HttpMultiServer.bind(hostname, port); fileSystem = AssetFileSystem.forTesting( - StandardFileSystem.instance, hostname, '$port', - retries: 1); + StandardFileSystem.instance, + hostname, + '$port', + retries: 1, + ); serveRequests(server, noisyHandler); }); @@ -193,28 +201,34 @@ test('cannot read non-existing file', () async { var entity = fileSystem.entityForUri(Uri.parse(_nonExistingFile)); await expectLater( - entity.readAsBytes(), throwsA(isA<FileSystemException>())); + entity.readAsBytes(), + throwsA(isA<FileSystemException>()), + ); }); - test('readAsString is faster than decoding result of readAsBytes', - () async { - var entity = fileSystem.entityForUri(Uri.parse(_existingFile)); + test( + 'readAsString is faster than decoding result of readAsBytes', + () async { + var entity = fileSystem.entityForUri(Uri.parse(_existingFile)); - Future<int> elapsedReadAsString() async { - var stopwatch = Stopwatch()..start(); - await expectLater(entity.readAsString(), isNotNull); - return stopwatch.elapsedMilliseconds; - } + Future<int> elapsedReadAsString() async { + var stopwatch = Stopwatch()..start(); + await expectLater(entity.readAsString(), isNotNull); + return stopwatch.elapsedMilliseconds; + } - Future<int> elapsedReadAsBytesAndDecode() async { - var stopwatch = Stopwatch()..start(); - await expectLater(utf8.decode(await entity.readAsBytes()), isNotNull); - return stopwatch.elapsedMilliseconds; - } + Future<int> elapsedReadAsBytesAndDecode() async { + var stopwatch = Stopwatch()..start(); + await expectLater(utf8.decode(await entity.readAsBytes()), isNotNull); + return stopwatch.elapsedMilliseconds; + } - await expectLater(await elapsedReadAsString(), - lessThan(await elapsedReadAsBytesAndDecode())); - }); + await expectLater( + await elapsedReadAsString(), + lessThan(await elapsedReadAsBytesAndDecode()), + ); + }, + ); test('can read a lot of files concurrently', () async { var fileContents = _largeFileContents(); @@ -233,8 +247,11 @@ server = await HttpMultiServer.bind(hostname, port); fileSystem = AssetFileSystem.forTesting( - StandardFileSystem.instance, hostname, '$port', - retries: 1); + StandardFileSystem.instance, + hostname, + '$port', + retries: 1, + ); serveRequests(server, unreliableHandler); }); @@ -272,15 +289,18 @@ test('cannot read non-existing file', () async { var entity = fileSystem.entityForUri(Uri.parse(_nonExistingFile)); await expectLater( - entity.readAsBytes(), throwsA(isA<FileSystemException>())); + entity.readAsBytes(), + throwsA(isA<FileSystemException>()), + ); }); test('can read a lot of files concurrently', () async { var futures = [ for (var i = 0; i < 512; i++) _expectContents( - fileSystem.entityForUri(Uri.parse(_uniqueExistingFile())), - _smallFileContents), + fileSystem.entityForUri(Uri.parse(_uniqueExistingFile())), + _smallFileContents, + ), ]; await Future.wait(futures); }, timeout: const Timeout.factor(2)); @@ -293,8 +313,11 @@ server = await HttpMultiServer.bind(hostname, port); fileSystem = AssetFileSystem.forTesting( - StandardFileSystem.instance, hostname, '$port', - retries: 0); + StandardFileSystem.instance, + hostname, + '$port', + retries: 0, + ); serveRequests(server, alwaysFailingHandler); }); @@ -317,19 +340,25 @@ test('cannot read existing file using readAsBytes', () async { var entity = fileSystem.entityForUri(Uri.parse(_existingFile)); await expectLater( - entity.readAsBytes(), throwsA(isA<FileSystemException>())); + entity.readAsBytes(), + throwsA(isA<FileSystemException>()), + ); }); test('cannot read existing file using readAsString', () async { var entity = fileSystem.entityForUri(Uri.parse(_existingFile)); await expectLater( - entity.readAsString(), throwsA(isA<FileSystemException>())); + entity.readAsString(), + throwsA(isA<FileSystemException>()), + ); }); test('cannot read non-existing file', () async { var entity = fileSystem.entityForUri(Uri.parse(_nonExistingFile)); await expectLater( - entity.readAsBytes(), throwsA(isA<FileSystemException>())); + entity.readAsBytes(), + throwsA(isA<FileSystemException>()), + ); }); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_common.dart b/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_common.dart index c4223b8..486f747 100644 --- a/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_common.dart +++ b/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_common.dart
@@ -9,8 +9,11 @@ import '../shared_test_options.dart'; import 'expression_compiler_e2e_suite.dart'; -void runTests(ExpressionEvaluationTestDriver driver, SetupCompilerOptions setup, - String mode) { +void runTests( + ExpressionEvaluationTestDriver driver, + SetupCompilerOptions setup, + String mode, +) { group('$mode mode', () { const source = r''' void main() { @@ -30,10 +33,9 @@ await driver.initSource(setup, source); expect( - File(driver.dartSdkPath).readAsStringSync(), - setup.canaryFeatures - ? contains('canary') - : isNot(contains('canary'))); + File(driver.dartSdkPath).readAsStringSync(), + setup.canaryFeatures ? contains('canary') : isNot(contains('canary')), + ); }); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_ddc_test.dart b/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_ddc_test.dart index 1fc3cf6..e72aa6e 100644 --- a/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_ddc_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_ddc_test.dart
@@ -11,8 +11,10 @@ void main(List<String> args) async { final driver = await ExpressionEvaluationTestDriver.init(); - final setup = - SetupCompilerOptions(moduleFormat: ModuleFormat.ddc, args: args); + final setup = SetupCompilerOptions( + moduleFormat: ModuleFormat.ddc, + args: args, + ); final mode = setup.canaryFeatures ? 'canary' : 'stable'; runTests(driver, setup, mode); }
diff --git a/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_test.dart b/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_test.dart index 5358501..159dd38 100644 --- a/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/canary_features_enabled_test.dart
@@ -11,8 +11,10 @@ void main(List<String> args) async { final driver = await ExpressionEvaluationTestDriver.init(); - final setup = - SetupCompilerOptions(moduleFormat: ModuleFormat.amd, args: args); + final setup = SetupCompilerOptions( + moduleFormat: ModuleFormat.amd, + args: args, + ); final mode = setup.canaryFeatures ? 'canary' : 'stable'; runTests(driver, setup, mode); }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart index 4f34c61..a61de41 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart
@@ -36,7 +36,9 @@ /// Shared tests for language features introduced in version 2.17.0. void runSharedTests( - SetupCompilerOptions setup, ExpressionEvaluationTestDriver driver) { + SetupCompilerOptions setup, + ExpressionEvaluationTestDriver driver, +) { group('Named arguments anywhere', () { var source = r''' String topLevelMethod(int param1, String param2, @@ -82,33 +84,38 @@ test('in top level method', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'topLevelMethod(param3: 3, 1, param4: "four", "two")', - expectedResult: '1, two, 3, four'); + breakpointId: 'bp', + expression: 'topLevelMethod(param3: 3, 1, param4: "four", "two")', + expectedResult: '1, two, 3, four', + ); }); test('in local method', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'topLevelMethod(param3: 3, 1, param4: "four", "two")', - expectedResult: '1, two, 3, four'); + breakpointId: 'bp', + expression: 'topLevelMethod(param3: 3, 1, param4: "four", "two")', + expectedResult: '1, two, 3, four', + ); }); test('in class constructor', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'C(param3: 3, 1, param4: "four", "two").toString()', - expectedResult: '1, two, 3, four'); + breakpointId: 'bp', + expression: 'C(param3: 3, 1, param4: "four", "two").toString()', + expectedResult: '1, two, 3, four', + ); }); test('in class static method', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'C.staticMethod(param3: 3, 1, param4: "four", "two")', - expectedResult: '1, two, 3, four'); + breakpointId: 'bp', + expression: 'C.staticMethod(param3: 3, 1, param4: "four", "two")', + expectedResult: '1, two, 3, four', + ); }); test('in class instance method', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'c.instanceMethod(param3: 3, 1, param4: "four", "two")', - expectedResult: '1, two, 3, four'); + breakpointId: 'bp', + expression: 'c.instanceMethod(param3: 3, 1, param4: "four", "two")', + expectedResult: '1, two, 3, four', + ); }); }); @@ -151,27 +158,57 @@ test('in constructor mixed with regular parameters', () async { await driver.checkInFrame( - breakpointId: 'bp', expression: 'c.i1', expectedResult: '1'); + breakpointId: 'bp', + expression: 'c.i1', + expectedResult: '1', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c.i', expectedResult: '2'); + breakpointId: 'bp', + expression: 'c.i', + expectedResult: '2', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c.i2', expectedResult: '3'); + breakpointId: 'bp', + expression: 'c.i2', + expectedResult: '3', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c.s', expectedResult: 'bar'); + breakpointId: 'bp', + expression: 'c.s', + expectedResult: 'bar', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c.d', expectedResult: '3.14'); + breakpointId: 'bp', + expression: 'c.d', + expectedResult: '3.14', + ); }); test('in named constructor mixed with regular parameters', () async { await driver.checkInFrame( - breakpointId: 'bp', expression: 'c2.i1', expectedResult: '10'); + breakpointId: 'bp', + expression: 'c2.i1', + expectedResult: '10', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c2.i', expectedResult: '20'); + breakpointId: 'bp', + expression: 'c2.i', + expectedResult: '20', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c2.i2', expectedResult: '30'); + breakpointId: 'bp', + expression: 'c2.i2', + expectedResult: '30', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c2.s', expectedResult: 'default'); + breakpointId: 'bp', + expression: 'c2.s', + expectedResult: 'default', + ); await driver.checkInFrame( - breakpointId: 'bp', expression: 'c2.d', expectedResult: '2.71'); + breakpointId: 'bp', + expression: 'c2.d', + expectedResult: '2.71', + ); }); }); @@ -217,63 +254,73 @@ test('evaluate to the correct string', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'E.id_string.toString()', - expectedResult: 'E.id_string'); + breakpointId: 'bp', + expression: 'E.id_string.toString()', + expectedResult: 'E.id_string', + ); }); test('evaluate to the correct index', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'E.id_string.index', - expectedResult: '2'); + breakpointId: 'bp', + expression: 'E.id_string.index', + expectedResult: '2', + ); }); test('compare properly against themselves', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'e == E.id_string && E.id_string == E.id_string', - expectedResult: 'true'); + breakpointId: 'bp', + expression: 'e == E.id_string && E.id_string == E.id_string', + expectedResult: 'true', + ); }); test('compare properly against other enums', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'e != E2.id_string && E.id_string != E2.id_string', - expectedResult: 'true'); + breakpointId: 'bp', + expression: 'e != E2.id_string && E.id_string != E2.id_string', + expectedResult: 'true', + ); }); test('with instance methods', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'E.id_bool.instanceMethod()', - expectedResult: '42'); + breakpointId: 'bp', + expression: 'E.id_bool.instanceMethod()', + expectedResult: '42', + ); }); test('with instance methods from local instance', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'e.instanceMethod()', - expectedResult: '13'); + breakpointId: 'bp', + expression: 'e.instanceMethod()', + expectedResult: '13', + ); }); test('with getters', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'E.id_int.fieldGetter', - expectedResult: '0'); + breakpointId: 'bp', + expression: 'E.id_int.fieldGetter', + expectedResult: '0', + ); }); test('with getters from local instance', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'e.fieldGetter', - expectedResult: 'hello world'); + breakpointId: 'bp', + expression: 'e.fieldGetter', + expectedResult: 'hello world', + ); }); test('with mixin calls', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'E.id_string.mixinMethod()', - expectedResult: '200'); + breakpointId: 'bp', + expression: 'E.id_string.mixinMethod()', + expectedResult: '200', + ); }); test('with mixin calls through overridden indices', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'E2.v2.mixinMethod()', - expectedResult: '100'); + breakpointId: 'bp', + expression: 'E2.v2.mixinMethod()', + expectedResult: '100', + ); }); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_0_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_0_test.dart index dde1118..8a9f6e2 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_0_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_0_test.dart
@@ -37,7 +37,9 @@ /// Shared tests for language features introduced in version 3.0.0. void runSharedTests( - SetupCompilerOptions setup, ExpressionEvaluationTestDriver driver) { + SetupCompilerOptions setup, + ExpressionEvaluationTestDriver driver, +) { group('Records', () { const recordsSource = ''' void main() { @@ -60,86 +62,98 @@ test('simple record', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'r.toString()', - expectedResult: '(true, 3)'); + breakpointId: 'bp', + expression: 'r.toString()', + expectedResult: '(true, 3)', + ); }); test('simple record type', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'r.runtimeType.toString()', - expectedResult: '(bool, int)'); + breakpointId: 'bp', + expression: 'r.runtimeType.toString()', + expectedResult: '(bool, int)', + ); }); test('simple record field one', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'r.\$1.toString()', - expectedResult: 'true'); + breakpointId: 'bp', + expression: 'r.\$1.toString()', + expectedResult: 'true', + ); }); test('simple record field two', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'r.\$2.toString()', - expectedResult: '3'); + breakpointId: 'bp', + expression: 'r.\$2.toString()', + expectedResult: '3', + ); }); test('complex record', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'cr.toString()', - expectedResult: '(true, {a: 1, b: 2})'); + breakpointId: 'bp', + expression: 'cr.toString()', + expectedResult: '(true, {a: 1, b: 2})', + ); }); test('complex record type', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'cr.runtimeType.toString()', - expectedResult: '(bool, IdentityMap<String, int>)'); + breakpointId: 'bp', + expression: 'cr.runtimeType.toString()', + expectedResult: '(bool, IdentityMap<String, int>)', + ); }); test('complex record field one', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'cr.\$1.toString()', - expectedResult: 'true'); + breakpointId: 'bp', + expression: 'cr.\$1.toString()', + expectedResult: 'true', + ); }); test('complex record field two', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'cr.\$2.toString()', - expectedResult: '{a: 1, b: 2}'); + breakpointId: 'bp', + expression: 'cr.\$2.toString()', + expectedResult: '{a: 1, b: 2}', + ); }); test('nested record', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'nr.toString()', - expectedResult: '(true, (false, 3))'); + breakpointId: 'bp', + expression: 'nr.toString()', + expectedResult: '(true, (false, 3))', + ); }); test('nested record type', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'nr.runtimeType.toString()', - expectedResult: '(bool, (bool, int))'); + breakpointId: 'bp', + expression: 'nr.runtimeType.toString()', + expectedResult: '(bool, (bool, int))', + ); }); test('nested record field one', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'nr.\$1.toString()', - expectedResult: 'true'); + breakpointId: 'bp', + expression: 'nr.\$1.toString()', + expectedResult: 'true', + ); }); test('nested record field two', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'nr.\$2.toString()', - expectedResult: '(false, 3)'); + breakpointId: 'bp', + expression: 'nr.\$2.toString()', + expectedResult: '(false, 3)', + ); }); }); @@ -179,54 +193,64 @@ test('first case match', () async { await driver.checkInFrame( - breakpointId: 'bp1', expression: 'a.toString()', expectedResult: '1'); + breakpointId: 'bp1', + expression: 'a.toString()', + expectedResult: '1', + ); }); test('second case match', () async { await driver.checkInFrame( - breakpointId: 'bp2', - expression: 'a.toString()', - expectedResult: '10'); + breakpointId: 'bp2', + expression: 'a.toString()', + expectedResult: '10', + ); }); test('default case match', () async { await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'obj.toString()', - expectedResult: '0'); + breakpointId: 'bp3', + expression: 'obj.toString()', + expectedResult: '0', + ); }); test('first case match result', () async { await driver.checkInFrame( - breakpointId: 'bp4', - expression: 'one.toString()', - expectedResult: '1'); + breakpointId: 'bp4', + expression: 'one.toString()', + expectedResult: '1', + ); }); test('second case match result', () async { await driver.checkInFrame( - breakpointId: 'bp4', - expression: 'ten.toString()', - expectedResult: '10'); + breakpointId: 'bp4', + expression: 'ten.toString()', + expectedResult: '10', + ); }); test('default match result', () async { await driver.checkInFrame( - breakpointId: 'bp4', - expression: 'zero.toString()', - expectedResult: '0'); + breakpointId: 'bp4', + expression: 'zero.toString()', + expectedResult: '0', + ); }); test('first case scope', () async { await driver.checkScope( - breakpointId: 'bp1', - expectedScope: {'a': '1', 'b': '2', 'obj': 'obj'}); + breakpointId: 'bp1', + expectedScope: {'a': '1', 'b': '2', 'obj': 'obj'}, + ); }); test('second case scope', () async { await driver.checkScope( - breakpointId: 'bp2', - expectedScope: {'a\$': '10', 'b\$': '\'20\'', 'obj': 'obj'}); + breakpointId: 'bp2', + expectedScope: {'a\$': '10', 'b\$': '\'20\'', 'obj': 'obj'}, + ); }); test('default case scope', () async { @@ -235,8 +259,9 @@ test('result scope', () async { await driver.checkScope( - breakpointId: 'bp4', - expectedScope: {'foo': 'foo', 'one': '1', 'ten': '10', 'zero': '0'}); + breakpointId: 'bp4', + expectedScope: {'foo': 'foo', 'one': '1', 'ten': '10', 'zero': '0'}, + ); }); }); @@ -288,150 +313,170 @@ group('bp1', () { test('a', () async { await driver.checkInFrame( - breakpointId: 'bp1', - expression: 'a.toString()', - expectedResult: '51'); + breakpointId: 'bp1', + expression: 'a.toString()', + expectedResult: '51', + ); }); test('a\$', () async { await driver.checkInFrame( - breakpointId: 'bp1', - expression: 'a\$.toString()', - expectedResult: '2'); + breakpointId: 'bp1', + expression: 'a\$.toString()', + expectedResult: '2', + ); }); test('a\$0', () async { await driver.checkInFrame( - breakpointId: 'bp1', - expression: 'a\$0.toString()', - expectedResult: '3'); + breakpointId: 'bp1', + expression: 'a\$0.toString()', + expectedResult: '3', + ); }); test('a\$360', () async { await driver.checkInFrame( - breakpointId: 'bp1', - expression: 'a\$360.toString()', - expectedResult: '4'); + breakpointId: 'bp1', + expression: 'a\$360.toString()', + expectedResult: '4', + ); }); }); group('bp2', () { test('a', () async { await driver.checkInFrame( - breakpointId: 'bp2', - expression: 'a.toString()', - expectedResult: '1'); + breakpointId: 'bp2', + expression: 'a.toString()', + expectedResult: '1', + ); }); test('a\$', () async { await driver.checkInFrame( - breakpointId: 'bp2', - expression: 'a\$.toString()', - expectedResult: '62'); + breakpointId: 'bp2', + expression: 'a\$.toString()', + expectedResult: '62', + ); }); test('a\$0', () async { await driver.checkInFrame( - breakpointId: 'bp2', - expression: 'a\$0.toString()', - expectedResult: '3'); + breakpointId: 'bp2', + expression: 'a\$0.toString()', + expectedResult: '3', + ); }); test('a\$360', () async { await driver.checkInFrame( - breakpointId: 'bp2', - expression: 'a\$360.toString()', - expectedResult: '4'); + breakpointId: 'bp2', + expression: 'a\$360.toString()', + expectedResult: '4', + ); }); }); group('bp3', () { test('a', () async { await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'a.toString()', - expectedResult: '1'); + breakpointId: 'bp3', + expression: 'a.toString()', + expectedResult: '1', + ); }); test('a\$', () async { await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'a\$.toString()', - expectedResult: '2'); + breakpointId: 'bp3', + expression: 'a\$.toString()', + expectedResult: '2', + ); }); test('a\$0', () async { await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'a\$0.toString()', - expectedResult: '73'); + breakpointId: 'bp3', + expression: 'a\$0.toString()', + expectedResult: '73', + ); }); test('a\$360', () async { await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'a\$360.toString()', - expectedResult: '4'); + breakpointId: 'bp3', + expression: 'a\$360.toString()', + expectedResult: '4', + ); }); }); group('bp4', () { test('a', () async { await driver.checkInFrame( - breakpointId: 'bp4', - expression: 'a.toString()', - expectedResult: '1'); + breakpointId: 'bp4', + expression: 'a.toString()', + expectedResult: '1', + ); }); test('a\$', () async { await driver.checkInFrame( - breakpointId: 'bp4', - expression: 'a\$.toString()', - expectedResult: '2'); + breakpointId: 'bp4', + expression: 'a\$.toString()', + expectedResult: '2', + ); }); test('a\$0', () async { await driver.checkInFrame( - breakpointId: 'bp4', - expression: 'a\$0.toString()', - expectedResult: '3'); + breakpointId: 'bp4', + expression: 'a\$0.toString()', + expectedResult: '3', + ); }); test('a\$360', () async { await driver.checkInFrame( - breakpointId: 'bp4', - expression: 'a\$360.toString()', - expectedResult: '84'); + breakpointId: 'bp4', + expression: 'a\$360.toString()', + expectedResult: '84', + ); }); }); group('bp5', () { test('a', () async { await driver.checkInFrame( - breakpointId: 'bp5', - expression: 'a.toString()', - expectedResult: '1'); + breakpointId: 'bp5', + expression: 'a.toString()', + expectedResult: '1', + ); }); test('a\$', () async { await driver.checkInFrame( - breakpointId: 'bp5', - expression: 'a\$.toString()', - expectedResult: '2'); + breakpointId: 'bp5', + expression: 'a\$.toString()', + expectedResult: '2', + ); }); test('a\$0', () async { await driver.checkInFrame( - breakpointId: 'bp5', - expression: 'a\$0.toString()', - expectedResult: '3'); + breakpointId: 'bp5', + expression: 'a\$0.toString()', + expectedResult: '3', + ); }); test('a\$360', () async { await driver.checkInFrame( - breakpointId: 'bp5', - expression: 'a\$360.toString()', - expectedResult: '4'); + breakpointId: 'bp5', + expression: 'a\$360.toString()', + expectedResult: '4', + ); }); }); });
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_7_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_7_test.dart index 0e74005..e5580e0 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_7_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_3_7_test.dart
@@ -40,7 +40,9 @@ /// Wildcards create local variables in scope that are unused. They should not /// interfere with expression evaluation in any way. void runSharedTests( - SetupCompilerOptions setup, ExpressionEvaluationTestDriver driver) { + SetupCompilerOptions setup, + ExpressionEvaluationTestDriver driver, +) { group('Wildcard', () { const recordsSource = ''' // @dart=3.7 @@ -84,39 +86,46 @@ test('method argument in scope do not break other evaluations', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'd.toString()', - expectedResult: '0:00:03.000000'); + breakpointId: 'bp', + expression: 'd.toString()', + expectedResult: '0:00:03.000000', + ); await driver.checkInFrame( - breakpointId: 'bp', - expression: '__.toString()', - expectedResult: 'two'); + breakpointId: 'bp', + expression: '__.toString()', + expectedResult: 'two', + ); }); test('local variable in scope do not break other evaluations', () async { await driver.checkInFrame( - breakpointId: 'bp2', - expression: 'd.toString()', - expectedResult: '0:00:03.000000'); + breakpointId: 'bp2', + expression: 'd.toString()', + expectedResult: '0:00:03.000000', + ); await driver.checkInFrame( - breakpointId: 'bp2', - expression: '__.toString()', - expectedResult: 'hello'); + breakpointId: 'bp2', + expression: '__.toString()', + expectedResult: 'hello', + ); }); test('type argument in scope do not break other evaluations', () async { await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'd.toString()', - expectedResult: '0:00:03.000000'); + breakpointId: 'bp3', + expression: 'd.toString()', + expectedResult: '0:00:03.000000', + ); await driver.checkInFrame( - breakpointId: 'bp3', - expression: '__.toString()', - expectedResult: 'world'); + breakpointId: 'bp3', + expression: '__.toString()', + expectedResult: 'world', + ); await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'T.toString()', - expectedResult: 'String'); + breakpointId: 'bp3', + expression: 'T.toString()', + expectedResult: 'String', + ); }); }); @@ -173,39 +182,46 @@ test('method argument in scope do not break other evaluations', () async { await driver.checkInFrame( - breakpointId: 'bp', - expression: 'd.toString()', - expectedResult: '0:00:03.000000'); + breakpointId: 'bp', + expression: 'd.toString()', + expectedResult: '0:00:03.000000', + ); await driver.checkInFrame( - breakpointId: 'bp', - expression: '__.toString()', - expectedResult: 'two'); + breakpointId: 'bp', + expression: '__.toString()', + expectedResult: 'two', + ); }); test('local variable in scope do not break other evaluations', () async { await driver.checkInFrame( - breakpointId: 'bp2', - expression: 'd.toString()', - expectedResult: '0:00:03.000000'); + breakpointId: 'bp2', + expression: 'd.toString()', + expectedResult: '0:00:03.000000', + ); await driver.checkInFrame( - breakpointId: 'bp2', - expression: '__.toString()', - expectedResult: 'hello'); + breakpointId: 'bp2', + expression: '__.toString()', + expectedResult: 'hello', + ); }); test('type argument in scope do not break other evaluations', () async { await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'd.toString()', - expectedResult: '0:00:03.000000'); + breakpointId: 'bp3', + expression: 'd.toString()', + expectedResult: '0:00:03.000000', + ); await driver.checkInFrame( - breakpointId: 'bp3', - expression: '__.toString()', - expectedResult: 'world'); + breakpointId: 'bp3', + expression: '__.toString()', + expectedResult: 'world', + ); await driver.checkInFrame( - breakpointId: 'bp3', - expression: 'T.toString()', - expectedResult: 'String'); + breakpointId: 'bp3', + expression: 'T.toString()', + expectedResult: 'String', + ); }); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart index 82ca4ac..feb40df 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
@@ -339,7 +339,9 @@ /// Shared tests that require a language version >=2.12.0 <2.17.0. void runNullSafeSharedTests( - SetupCompilerOptions setup, ExpressionEvaluationTestDriver driver) { + SetupCompilerOptions setup, + ExpressionEvaluationTestDriver driver, +) { group('JS interop', () { const interopSource = r''' @JS() @@ -414,45 +416,51 @@ group('static interop', () { test('call extension methods of existing JS object', () async { await driver.checkInFrame( - breakpointId: 'staticInteropBP', - expression: 'dartCounter.value', - expectedResult: '2'); + breakpointId: 'staticInteropBP', + expression: 'dartCounter.value', + expectedResult: '2', + ); await driver.checkInFrame( - breakpointId: 'staticInteropBP', - expression: 'jsCounter.value', - expectedResult: '2'); + breakpointId: 'staticInteropBP', + expression: 'jsCounter.value', + expectedResult: '2', + ); }); test('call extension methods of a new JS object', () async { await driver.checkInFrame( - breakpointId: 'staticInteropBP', - expression: - '(createDartExport<Counter>(dartCounter) as JSCounter).value', - expectedResult: '2'); + breakpointId: 'staticInteropBP', + expression: + '(createDartExport<Counter>(dartCounter) as JSCounter).value', + expectedResult: '2', + ); }); }); group('extension types', () { test('call extension getters on existing JS object', () async { await driver.checkInFrame( - breakpointId: 'extensionTypesBP', - expression: 'dartCounter.value', - expectedResult: '2'); + breakpointId: 'extensionTypesBP', + expression: 'dartCounter.value', + expectedResult: '2', + ); await driver.checkInFrame( - breakpointId: 'extensionTypesBP', - expression: 'jsCounter.value', - expectedResult: '2'); + breakpointId: 'extensionTypesBP', + expression: 'jsCounter.value', + expectedResult: '2', + ); }); test('call extension getters on a new JS object', () async { await driver.checkInFrame( - breakpointId: 'extensionTypesBP', - expression: - 'JSCounter2(createDartExport<Counter>(dartCounter) as JSObject)' - '.value', - expectedResult: '2'); + breakpointId: 'extensionTypesBP', + expression: + 'JSCounter2(createDartExport<Counter>(dartCounter) as JSObject)' + '.value', + expectedResult: '2', + ); }); }); }); @@ -469,372 +477,426 @@ group('Exceptions', () { test('error', () async { await driver.checkInFrame( - breakpointId: 'exceptionBP', - expression: 'e.toString()', - expectedResult: 'meow!'); + breakpointId: 'exceptionBP', + expression: 'e.toString()', + expectedResult: 'meow!', + ); }); test('stack trace', () async { await driver.checkInFrame( - breakpointId: 'exceptionBP', - expression: 's.toString()', - expectedResult: ''); + breakpointId: 'exceptionBP', + expression: 's.toString()', + expectedResult: '', + ); }); test('scope', () async { - await driver.checkScope(breakpointId: 'exceptionBP', expectedScope: { - 'e': 'e', - 's': 's', - }); + await driver.checkScope( + breakpointId: 'exceptionBP', + expectedScope: {'e': 'e', 's': 's'}, + ); }); }); group('Correct null safety mode used', () { test('in original source compilation', () async { await driver.checkInFrame( - breakpointId: 'soundNullSafetyBP', - expression: 'soundNullSafety', - expectedResult: 'true'); + breakpointId: 'soundNullSafetyBP', + expression: 'soundNullSafety', + expectedResult: 'true', + ); }); test('in expression compilation', () async { await driver.checkInFrame( - breakpointId: 'soundNullSafetyBP', - expression: '!(<Null>[] is List<int>)', - expectedResult: 'true'); + breakpointId: 'soundNullSafetyBP', + expression: '!(<Null>[] is List<int>)', + expectedResult: 'true', + ); }); }); group('library level', () { test('generic instantiation', () async { await driver.check( - expression: '[B(1,1).toString(), B(2,2).toString()]', - expectedResult: allOf( - contains('Array(2)'), - contains('0: Instance of \'B\''), - contains('1: Instance of \'B\''), - contains('length: 2'))); + expression: '[B(1,1).toString(), B(2,2).toString()]', + expectedResult: allOf( + contains('Array(2)'), + contains('0: Instance of \'B\''), + contains('1: Instance of \'B\''), + contains('length: 2'), + ), + ); }); - test('invoke an SDK method', () async { - await driver.check( + test( + 'invoke an SDK method', + () async { + await driver.check( expression: 'Flow.begin(id: 0) is Flow', libraryUri: Uri.parse('dart:developer'), - expectedResult: 'true'); - }, - // The new module format requires a per-library compiler. Since we - // loaded the SDK from a summary/dill, we've never actually created a - // compiler for it, and therefore can't execute library-level - // expression evaluation in the SDK. Currently, no real workflow can - // meaningfully use this anyways. See - // https://github.com/flutter/devtools/issues/7766 for the initial - // motivation. - skip: setup.emitLibraryBundle); + expectedResult: 'true', + ); + }, + // The new module format requires a per-library compiler. Since we + // loaded the SDK from a summary/dill, we've never actually created a + // compiler for it, and therefore can't execute library-level + // expression evaluation in the SDK. Currently, no real workflow can + // meaningfully use this anyways. See + // https://github.com/flutter/devtools/issues/7766 for the initial + // motivation. + skip: setup.emitLibraryBundle, + ); - test('tearoff an SDK method', () async { - await driver.check( + test( + 'tearoff an SDK method', + () async { + await driver.check( expression: 'postEvent', libraryUri: Uri.parse('dart:developer'), - expectedResult: contains('function postEvent(eventKind')); - }, - // The new module format requires a per-library compiler. Since we - // loaded the SDK from a summary/dill, we've never actually created a - // compiler for it, and therefore can't execute library-level - // expression evaluation in the SDK. Currently, no real workflow can - // meaningfully use this anyways. See - // https://github.com/flutter/devtools/issues/7766 for the initial - // motivation. - skip: setup.emitLibraryBundle); + expectedResult: contains('function postEvent(eventKind'), + ); + }, + // The new module format requires a per-library compiler. Since we + // loaded the SDK from a summary/dill, we've never actually created a + // compiler for it, and therefore can't execute library-level + // expression evaluation in the SDK. Currently, no real workflow can + // meaningfully use this anyways. See + // https://github.com/flutter/devtools/issues/7766 for the initial + // motivation. + skip: setup.emitLibraryBundle, + ); }); group('method level', () { test('tear off default constructor', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'C.new.runtimeType.toString()', - expectedResult: '(int, int) => C'); + breakpointId: 'methodBP', + expression: 'C.new.runtimeType.toString()', + expectedResult: '(int, int) => C', + ); }); test('call default constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: '(C.new)(0, 0)', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 0'))); + breakpointId: 'methodBP', + expression: '(C.new)(0, 0)', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 0'), + ), + ); }); test('tear off named constructor', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'C.named.runtimeType.toString()', - expectedResult: '(int) => C'); + breakpointId: 'methodBP', + expression: 'C.named.runtimeType.toString()', + expectedResult: '(int) => C', + ); }); test('call named constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: '(C.named)(0)', - expectedResult: allOf( - contains('test.C.named'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 42'))); + breakpointId: 'methodBP', + expression: '(C.named)(0)', + expectedResult: allOf( + contains('test.C.named'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 42'), + ), + ); }); test('tear off redirecting constructor', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'C.redirecting.runtimeType.toString()', - expectedResult: '(int) => C'); + breakpointId: 'methodBP', + expression: 'C.redirecting.runtimeType.toString()', + expectedResult: '(int) => C', + ); }); test('call redirecting constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: '(C.redirecting)(0)', - expectedResult: allOf( - contains('test.C.redirecting'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 99'))); + breakpointId: 'methodBP', + expression: '(C.redirecting)(0)', + expectedResult: allOf( + contains('test.C.redirecting'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 99'), + ), + ); }); test('tear off factory constructor', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'C.factory.runtimeType.toString()', - expectedResult: '() => C'); + breakpointId: 'methodBP', + expression: 'C.factory.runtimeType.toString()', + expectedResult: '() => C', + ); }); test('call factory constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: '(C.factory)()', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 42'), - contains('Symbol(_field): 0'))); + breakpointId: 'methodBP', + expression: '(C.factory)()', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 42'), + contains('Symbol(_field): 0'), + ), + ); }); test('map access', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: ''' + breakpointId: 'methodBP', + expression: ''' (Map<String, String> params) { return params["a"]; }({"a":"b"}) ''', - expectedResult: 'b'); + expectedResult: 'b', + ); }); }); group('top-level method', () { test('tear off default constructor', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C.new.runtimeType.toString()', - expectedResult: '(int, int) => C'); + breakpointId: 'globalFunctionBP', + expression: 'C.new.runtimeType.toString()', + expectedResult: '(int, int) => C', + ); }); test('call default constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: '(C.new)(0, 0)', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 0'))); + breakpointId: 'globalFunctionBP', + expression: '(C.new)(0, 0)', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 0'), + ), + ); }); test('tear off named constructor', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C.named.runtimeType.toString()', - expectedResult: '(int) => C'); + breakpointId: 'globalFunctionBP', + expression: 'C.named.runtimeType.toString()', + expectedResult: '(int) => C', + ); }); test('call named constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: '(C.named)(0)', - expectedResult: allOf( - contains('test.C.named'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 42'))); + breakpointId: 'globalFunctionBP', + expression: '(C.named)(0)', + expectedResult: allOf( + contains('test.C.named'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 42'), + ), + ); }); test('tear off redirecting constructor', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C.redirecting.runtimeType.toString()', - expectedResult: '(int) => C'); + breakpointId: 'globalFunctionBP', + expression: 'C.redirecting.runtimeType.toString()', + expectedResult: '(int) => C', + ); }); test('call redirecting constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: '(C.redirecting)(0)', - expectedResult: allOf( - contains('test.C.redirecting'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 99'))); + breakpointId: 'globalFunctionBP', + expression: '(C.redirecting)(0)', + expectedResult: allOf( + contains('test.C.redirecting'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 99'), + ), + ); }); test('tear off factory constructor', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C.factory.runtimeType.toString()', - expectedResult: '() => C'); + breakpointId: 'globalFunctionBP', + expression: 'C.factory.runtimeType.toString()', + expectedResult: '() => C', + ); }); test('call factory constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: '(C.factory)()', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 42'), - contains('Symbol(_field): 0'))); + breakpointId: 'globalFunctionBP', + expression: '(C.factory)()', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 42'), + contains('Symbol(_field): 0'), + ), + ); }); }); group('constructors', () { test('tear off default constructor', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'C.new.runtimeType.toString()', - expectedResult: '(int, int) => C'); + breakpointId: 'constructorBP', + expression: 'C.new.runtimeType.toString()', + expectedResult: '(int, int) => C', + ); }); test('call default constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: '(C.new)(0, 0)', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 0'))); + breakpointId: 'constructorBP', + expression: '(C.new)(0, 0)', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 0'), + ), + ); }); test('tear off named constructor', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'C.named.runtimeType.toString()', - expectedResult: '(int) => C'); + breakpointId: 'constructorBP', + expression: 'C.named.runtimeType.toString()', + expectedResult: '(int) => C', + ); }); test('call named constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: '(C.named)(0)', - expectedResult: allOf( - contains('test.C.named'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 42'))); + breakpointId: 'constructorBP', + expression: '(C.named)(0)', + expectedResult: allOf( + contains('test.C.named'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 42'), + ), + ); }); test('tear off redirecting constructor', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'C.redirecting.runtimeType.toString()', - expectedResult: '(int) => C'); + breakpointId: 'constructorBP', + expression: 'C.redirecting.runtimeType.toString()', + expectedResult: '(int) => C', + ); }); test('call redirecting constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: '(C.redirecting)(0)', - expectedResult: allOf( - contains('test.C.redirecting'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 0'), - contains('Symbol(_field): 99'))); + breakpointId: 'constructorBP', + expression: '(C.redirecting)(0)', + expectedResult: allOf( + contains('test.C.redirecting'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 0'), + contains('Symbol(_field): 99'), + ), + ); }); test('tear off factory constructor', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'C.factory.runtimeType.toString()', - expectedResult: '() => C'); + breakpointId: 'constructorBP', + expression: 'C.factory.runtimeType.toString()', + expectedResult: '() => C', + ); }); test('call factory constructor tear off', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: '(C.factory)()', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.list): Array(0)'), - contains('Symbol(C.field): 42'), - contains('Symbol(_field): 0'))); + breakpointId: 'constructorBP', + expression: '(C.factory)()', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.list): Array(0)'), + contains('Symbol(C.field): 42'), + contains('Symbol(_field): 0'), + ), + ); }); }); group('enums', () { test('evaluate to the correct string', () async { await driver.checkInFrame( - breakpointId: 'enumBP', - expression: 'E.id2.toString()', - expectedResult: 'E.id2'); + breakpointId: 'enumBP', + expression: 'E.id2.toString()', + expectedResult: 'E.id2', + ); }); test('evaluate to the correct index', () async { await driver.checkInFrame( - breakpointId: 'enumBP', - expression: 'E.id3.index', - expectedResult: '2'); + breakpointId: 'enumBP', + expression: 'E.id3.index', + expectedResult: '2', + ); }); test('compare properly against themselves', () async { await driver.checkInFrame( - breakpointId: 'enumBP', - expression: 'e == E.id2 && E.id2 == E.id2', - expectedResult: 'true'); + breakpointId: 'enumBP', + expression: 'e == E.id2 && E.id2 == E.id2', + expectedResult: 'true', + ); }); test('compare properly against other enums', () async { await driver.checkInFrame( - breakpointId: 'enumBP', - expression: 'e != E2.id2 && E.id2 != E2.id2', - expectedResult: 'true'); + breakpointId: 'enumBP', + expression: 'e != E2.id2 && E.id2 != E2.id2', + expectedResult: 'true', + ); }); test('scope', () async { - await driver.checkScope(breakpointId: 'enumBP', expectedScope: { - 'e': 'e', - }); + await driver.checkScope( + breakpointId: 'enumBP', + expectedScope: {'e': 'e'}, + ); }); }); group('late', () { group('local', () { - test( - 'can be evaluated when initialized', - () async { - await driver.checkInFrame( - breakpointId: 'lateLocalVariableBP', - expression: 'lateLocal', - expectedResult: '42'); - }, - ); + test('can be evaluated when initialized', () async { + await driver.checkInFrame( + breakpointId: 'lateLocalVariableBP', + expression: 'lateLocal', + expectedResult: '42', + ); + }); test('does not throw when evaluated and not initialized', () async { // It isn't clear if this is expected to work or not, the behavior is // somewhat undefined for the debugger. At this time we expose the @@ -842,9 +904,10 @@ // uninitialized. // See https://github.com/dart-lang/sdk/issues/55918 await driver.checkInFrame( - breakpointId: 'lateLocalVariableBP', - expression: 'lateLocal2', - expectedResult: 'null'); + breakpointId: 'lateLocalVariableBP', + expression: 'lateLocal2', + expectedResult: 'null', + ); }); test('throws when not initialized and used in method call', () async { // It isn't clear if this is expected to work or not, the behavior is @@ -853,25 +916,30 @@ // uninitialized. // See https://github.com/dart-lang/sdk/issues/55918 await driver.checkInFrame( - breakpointId: 'lateLocalVariableBP', - expression: 'lateLocal2.isEven', - expectedError: "Error: Property 'isEven' cannot be accessed on " - "'int?' because it is potentially null."); + breakpointId: 'lateLocalVariableBP', + expression: 'lateLocal2.isEven', + expectedError: + "Error: Property 'isEven' cannot be accessed on " + "'int?' because it is potentially null.", + ); }); }); group('global', () { test('can be evaluated when initialized', () async { await driver.checkInFrame( - breakpointId: 'lateGlobalVariableBP', - expression: 'lateGlobal', - expectedResult: '42'); + breakpointId: 'lateGlobalVariableBP', + expression: 'lateGlobal', + expectedResult: '42', + ); }); test('throws when not initialized', () async { await driver.checkInFrame( - breakpointId: 'lateGlobalVariableBP', - expression: 'lateGlobal2', - expectedError: 'Error: LateInitializationError: ' - "Field 'lateGlobal2' has not been initialized."); + breakpointId: 'lateGlobalVariableBP', + expression: 'lateGlobal2', + expectedError: + 'Error: LateInitializationError: ' + "Field 'lateGlobal2' has not been initialized.", + ); }); }); }); @@ -883,9 +951,10 @@ // location and the use of the wrong null literal value. This verifies // the expression compiler can safely compile this pattern. await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: '((){bool fn(bool b) {return b;} return fn(true);})()', - expectedResult: 'true'); + breakpointId: 'globalFunctionBP', + expression: '((){bool fn(bool b) {return b;} return fn(true);})()', + expectedResult: 'true', + ); }); test('don\'t crash on synthetic variables', () async { @@ -895,9 +964,10 @@ // the expression compiler // https://github.com/dart-lang/sdk/issues/49373. await driver.checkInFrame( - breakpointId: 'couldReturnNullBP', - expression: 'true', - expectedResult: 'true'); + breakpointId: 'couldReturnNullBP', + expression: 'true', + expectedResult: 'true', + ); }); }); }); @@ -912,7 +982,9 @@ /// This group of tests has been sharded manually. The others are in /// [runAgnosticSharedTestsShard2]. void runAgnosticSharedTestsShard1( - SetupCompilerOptions setup, ExpressionEvaluationTestDriver driver) { + SetupCompilerOptions setup, + ExpressionEvaluationTestDriver driver, +) { group('shared source', () { setUpAll(() async { await driver.initSource(setup, sharedSource); @@ -925,420 +997,488 @@ group('Correct null safety mode used', () { test('in original source compilation', () async { await driver.checkInFrame( - breakpointId: 'soundNullSafetyBP', - expression: 'soundNullSafety', - expectedResult: 'true'); + breakpointId: 'soundNullSafetyBP', + expression: 'soundNullSafety', + expectedResult: 'true', + ); }); test('in expression compilation', () async { await driver.checkInFrame( - breakpointId: 'soundNullSafetyBP', - expression: '!(<Null>[] is List<int>)', - expectedResult: 'true'); + breakpointId: 'soundNullSafetyBP', + expression: '!(<Null>[] is List<int>)', + expectedResult: 'true', + ); }); }); group('scope collection', () { test('local in scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'inScope', - expectedResult: '1'); + breakpointId: 'innerScopeBP', + expression: 'inScope', + expectedResult: '1', + ); }); test('local in inner scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'innerInScope', - expectedResult: '48'); + breakpointId: 'innerScopeBP', + expression: 'innerInScope', + expectedResult: '48', + ); }); test('global in scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'global', - expectedResult: '42'); + breakpointId: 'innerScopeBP', + expression: 'global', + expectedResult: '42', + ); }); test('static field in scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'staticField', - expectedResult: '1'); + breakpointId: 'innerScopeBP', + expression: 'staticField', + expectedResult: '1', + ); }); test('field in scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'field', - expectedResult: '5'); + breakpointId: 'innerScopeBP', + expression: 'field', + expectedResult: '5', + ); }); test('parameter in scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'x', - expectedResult: '10'); + breakpointId: 'innerScopeBP', + expression: 'x', + expectedResult: '10', + ); }); test('local not in scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'notInScope', - expectedError: - "Error: The getter 'notInScope' isn't defined for the" - " class 'C'."); + breakpointId: 'innerScopeBP', + expression: 'notInScope', + expectedError: + "Error: The getter 'notInScope' isn't defined for the" + " class 'C'.", + ); }); test('local not in inner scope', () async { await driver.checkInFrame( - breakpointId: 'innerScopeBP', - expression: 'innerNotInScope', - expectedError: - "Error: The getter 'innerNotInScope' isn't defined for the" - " class 'C'."); + breakpointId: 'innerScopeBP', + expression: 'innerNotInScope', + expectedError: + "Error: The getter 'innerNotInScope' isn't defined for the" + " class 'C'.", + ); }); }); group('ddc-extension symbols', () { test('extension symbol used only in expression compilation', () async { await driver.checkInFrame( - breakpointId: 'extensionSymbolsBP', - expression: 'list.first', - expectedResult: '0'); + breakpointId: 'extensionSymbolsBP', + expression: 'list.first', + expectedResult: '0', + ); }); test('extension symbol used in original compilation', () async { await driver.checkInFrame( - breakpointId: 'extensionSymbolsBP', - expression: '() { list.add(1); return list.last; }()', - expectedResult: '1'); + breakpointId: 'extensionSymbolsBP', + expression: '() { list.add(1); return list.last; }()', + expectedResult: '1', + ); }); }); group('Expression compiler tests in extension method:', () { test('compilation error', () async { await driver.checkInFrame( - breakpointId: 'parseIntPlusOneBP', - expression: 'typo', - expectedError: "Error: The getter 'typo' isn't defined"); + breakpointId: 'parseIntPlusOneBP', + expression: 'typo', + expectedError: "Error: The getter 'typo' isn't defined", + ); }); test('local (trimmed scope)', () async { await driver.checkInFrame( - breakpointId: 'parseIntPlusOneBP', - expression: 'ret', - expectedResult: '1234'); + breakpointId: 'parseIntPlusOneBP', + expression: 'ret', + expectedResult: '1234', + ); }); test('this (full scope)', () async { await driver.checkInFrame( - breakpointId: 'parseIntPlusOneBP', - expression: 'this', - expectedResult: '1234'); + breakpointId: 'parseIntPlusOneBP', + expression: 'this', + expectedResult: '1234', + ); }); test('scope', () async { - await driver - .checkScope(breakpointId: 'parseIntPlusOneBP', expectedScope: { - r'$this': '\'1234\'', - 'ret': '1234', - }); + await driver.checkScope( + breakpointId: 'parseIntPlusOneBP', + expectedScope: {r'$this': '\'1234\'', 'ret': '1234'}, + ); }); }); group('Expression compiler tests in static function:', () { test('compilation error', () async { await driver.checkInFrame( - breakpointId: 'fooBP', - expression: 'typo', - expectedError: "Undefined name 'typo'"); + breakpointId: 'fooBP', + expression: 'typo', + expectedError: "Undefined name 'typo'", + ); }); test('local', () async { await driver.checkInFrame( - breakpointId: 'fooBP', expression: 'x', expectedResult: '1'); + breakpointId: 'fooBP', + expression: 'x', + expectedResult: '1', + ); }); test('formal', () async { await driver.checkInFrame( - breakpointId: 'fooBP', expression: 'y', expectedResult: '2'); + breakpointId: 'fooBP', + expression: 'y', + expectedResult: '2', + ); }); test('named formal', () async { await driver.checkInFrame( - breakpointId: 'fooBP', expression: 'z', expectedResult: '3'); + breakpointId: 'fooBP', + expression: 'z', + expectedResult: '3', + ); }); test('function', () async { await driver.checkInFrame( - breakpointId: 'fooBP', - expression: 'callFooTest', - expectedResult: ''' + breakpointId: 'fooBP', + expression: 'callFooTest', + expectedResult: ''' function callFooTest() { return test.foo(1, {y: 2}); - }'''); + }''', + ); }); }); group('method level', () { test('compilation error', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'typo', - expectedError: "The getter 'typo' isn't defined for the class 'C'"); + breakpointId: 'methodBP', + expression: 'typo', + expectedError: "The getter 'typo' isn't defined for the class 'C'", + ); }); test('local', () async { await driver.checkInFrame( - breakpointId: 'methodBP', expression: 'x', expectedResult: '10'); + breakpointId: 'methodBP', + expression: 'x', + expectedResult: '10', + ); }); test('this', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'this', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.field): 5'), - contains('Symbol(_field): 6'))); + breakpointId: 'methodBP', + expression: 'this', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.field): 5'), + contains('Symbol(_field): 6'), + ), + ); }); test('expression using locals', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'x + 1', - expectedResult: '11'); + breakpointId: 'methodBP', + expression: 'x + 1', + expectedResult: '11', + ); }); test('expression using static fields', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'x + staticField', - expectedResult: '11'); + breakpointId: 'methodBP', + expression: 'x + staticField', + expectedResult: '11', + ); }); test('expression using private static fields', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'x + _staticField', - expectedResult: '12'); + breakpointId: 'methodBP', + expression: 'x + _staticField', + expectedResult: '12', + ); }); test('expression using fields', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'x + field', - expectedResult: '15'); + breakpointId: 'methodBP', + expression: 'x + field', + expectedResult: '15', + ); }); test('expression using private fields', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'x + _field', - expectedResult: '16'); + breakpointId: 'methodBP', + expression: 'x + _field', + expectedResult: '16', + ); }); test('expression using globals', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'x + global', - expectedResult: '52'); + breakpointId: 'methodBP', + expression: 'x + global', + expectedResult: '52', + ); }); - test('expression using fields not referred to in the original code', - () async { - await driver.checkInFrame( + test( + 'expression using fields not referred to in the original code', + () async { + await driver.checkInFrame( breakpointId: 'methodBP', expression: '_unusedField + _unusedStaticField', - expectedResult: '7'); - }); + expectedResult: '7', + ); + }, + ); test('private field modification', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: '_field = 2', - expectedResult: '2'); + breakpointId: 'methodBP', + expression: '_field = 2', + expectedResult: '2', + ); }); test('field modification', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'field = 3', - expectedResult: '3'); + breakpointId: 'methodBP', + expression: 'field = 3', + expectedResult: '3', + ); }); test('private static field modification', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: '_staticFieldB = 4', - expectedResult: '4'); + breakpointId: 'methodBP', + expression: '_staticFieldB = 4', + expectedResult: '4', + ); }); test('static field modification', () async { await driver.checkInFrame( - breakpointId: 'methodBP', - expression: 'staticFieldB = 5', - expectedResult: '5'); + breakpointId: 'methodBP', + expression: 'staticFieldB = 5', + expectedResult: '5', + ); }); }); group('global function', () { test('compilation error', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'typo', - expectedError: "Undefined name 'typo'."); + breakpointId: 'globalFunctionBP', + expression: 'typo', + expectedError: "Undefined name 'typo'.", + ); }); test('local with primitive type', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'x', - expectedResult: '15'); + breakpointId: 'globalFunctionBP', + expression: 'x', + expectedResult: '15', + ); }); test('local object', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'c', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.field): 5'), - contains('Symbol(_field): 6'))); + breakpointId: 'globalFunctionBP', + expression: 'c', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.field): 5'), + contains('Symbol(_field): 6'), + ), + ); }); test('create new object', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C(3, 4)', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.field): 3'), - contains('Symbol(_field): 4'))); + breakpointId: 'globalFunctionBP', + expression: 'C(3, 4)', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.field): 3'), + contains('Symbol(_field): 4'), + ), + ); }); test('access field of new object', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C(3, 4)._field', - expectedResult: '4'); + breakpointId: 'globalFunctionBP', + expression: 'C(3, 4)._field', + expectedResult: '4', + ); }); test('access static field', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C.staticField', - expectedResult: '1'); + breakpointId: 'globalFunctionBP', + expression: 'C.staticField', + expectedResult: '1', + ); }); test('expression using private static fields', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C._staticField', - expectedResult: '2'); + breakpointId: 'globalFunctionBP', + expression: 'C._staticField', + expectedResult: '2', + ); }); test('access field', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'c.field', - expectedResult: '5'); + breakpointId: 'globalFunctionBP', + expression: 'c.field', + expectedResult: '5', + ); }); test('access private field', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'c._field', - expectedResult: '6'); + breakpointId: 'globalFunctionBP', + expression: 'c._field', + expectedResult: '6', + ); }); test('method call', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'c.methodFieldAccess(2)', - expectedResult: '10'); + breakpointId: 'globalFunctionBP', + expression: 'c.methodFieldAccess(2)', + expectedResult: '10', + ); }); test('async method call', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'c.asyncMethod(2).runtimeType.toString()', - expectedResult: '_Future<int>'); + breakpointId: 'globalFunctionBP', + expression: 'c.asyncMethod(2).runtimeType.toString()', + expectedResult: '_Future<int>', + ); }); test('extension method call', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: '"1234".parseIntPlusOne()', - expectedResult: '1235'); + breakpointId: 'globalFunctionBP', + expression: '"1234".parseIntPlusOne()', + expectedResult: '1235', + ); }); test('private field modification', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'c._field = 10', - expectedResult: '10'); + breakpointId: 'globalFunctionBP', + expression: 'c._field = 10', + expectedResult: '10', + ); }); test('field modification', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'c._field = 11', - expectedResult: '11'); + breakpointId: 'globalFunctionBP', + expression: 'c._field = 11', + expectedResult: '11', + ); }); test('private static field modification', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C._staticField = 2', - expectedResult: '2'); + breakpointId: 'globalFunctionBP', + expression: 'C._staticField = 2', + expectedResult: '2', + ); }); test('static field modification', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'C.staticFieldC = 20', - expectedResult: '20'); + breakpointId: 'globalFunctionBP', + expression: 'C.staticFieldC = 20', + expectedResult: '20', + ); }); test('call global function from core library', () async { await driver.checkInFrame( - breakpointId: 'globalFunctionBP', - expression: 'identical(1, 1)', - expectedResult: 'true'); + breakpointId: 'globalFunctionBP', + expression: 'identical(1, 1)', + expectedResult: 'true', + ); }); }); group('async function', () { test('local variable', () async { await driver.checkInFrame( - breakpointId: 'asyncClosureBP0', - expression: 'test', - expectedResult: '0'); + breakpointId: 'asyncClosureBP0', + expression: 'test', + expectedResult: '0', + ); await driver.checkInFrame( - breakpointId: 'asyncClosureBP1', - expression: 'test', - expectedResult: '1'); + breakpointId: 'asyncClosureBP1', + expression: 'test', + expectedResult: '1', + ); await driver.checkInFrame( - breakpointId: 'asyncClosureBP2', - expression: 'test', - expectedResult: '2'); + breakpointId: 'asyncClosureBP2', + expression: 'test', + expectedResult: '2', + ); await driver.checkInFrame( - breakpointId: 'asyncClosureBP3', - expression: 'notTest', - expectedError: "Undefined name 'notTest'"); + breakpointId: 'asyncClosureBP3', + expression: 'notTest', + expectedError: "Undefined name 'notTest'", + ); await driver.checkInFrame( - breakpointId: 'asyncClosureBP4', - expression: 'unused', - expectedError: 'Value not found in scope'); + breakpointId: 'asyncClosureBP4', + expression: 'unused', + expectedError: 'Value not found in scope', + ); }); }); }); @@ -1353,7 +1493,9 @@ /// This group of tests has been sharded manually. The others are in /// [runAgnosticSharedTestsShard1]. void runAgnosticSharedTestsShard2( - SetupCompilerOptions setup, ExpressionEvaluationTestDriver driver) { + SetupCompilerOptions setup, + ExpressionEvaluationTestDriver driver, +) { group('shared source', () { setUpAll(() async { await driver.initSource(setup, sharedSource); @@ -1366,223 +1508,271 @@ group('constructor', () { test('compilation error', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'typo', - expectedError: "The getter 'typo' isn't defined for the class 'C'"); + breakpointId: 'constructorBP', + expression: 'typo', + expectedError: "The getter 'typo' isn't defined for the class 'C'", + ); }); test('local', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'y', - expectedResult: '1'); + breakpointId: 'constructorBP', + expression: 'y', + expectedResult: '1', + ); }); test('this', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'this', - expectedResult: allOf( - contains('test.C.new'), - contains('Symbol(_unusedField): 4'), - contains('Symbol(C.field): 5'), - contains('Symbol(_field): 6'))); + breakpointId: 'constructorBP', + expression: 'this', + expectedResult: allOf( + contains('test.C.new'), + contains('Symbol(_unusedField): 4'), + contains('Symbol(C.field): 5'), + contains('Symbol(_field): 6'), + ), + ); }); test('expression using locals', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'y + 1', - expectedResult: '2'); + breakpointId: 'constructorBP', + expression: 'y + 1', + expectedResult: '2', + ); }); test('expression using static fields', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'y + staticField', - expectedResult: '2'); + breakpointId: 'constructorBP', + expression: 'y + staticField', + expectedResult: '2', + ); }); test('expression using private static fields', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'y + _staticField', - expectedResult: '3'); + breakpointId: 'constructorBP', + expression: 'y + _staticField', + expectedResult: '3', + ); }); test('expression using fields', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'y + field', - expectedResult: '6'); + breakpointId: 'constructorBP', + expression: 'y + field', + expectedResult: '6', + ); }); test('expression using private fields', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'y + _field', - expectedResult: '7'); + breakpointId: 'constructorBP', + expression: 'y + _field', + expectedResult: '7', + ); }); test('expression using globals', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'y + global', - expectedResult: '43'); + breakpointId: 'constructorBP', + expression: 'y + global', + expectedResult: '43', + ); }); test('method call', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'methodFieldAccess(2)', - expectedResult: '10'); + breakpointId: 'constructorBP', + expression: 'methodFieldAccess(2)', + expectedResult: '10', + ); }); test('async method call', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'asyncMethod(2).runtimeType.toString()', - expectedResult: '_Future<int>'); + breakpointId: 'constructorBP', + expression: 'asyncMethod(2).runtimeType.toString()', + expectedResult: '_Future<int>', + ); }); test('extension method call', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: '"1234".parseIntPlusOne()', - expectedResult: '1235'); + breakpointId: 'constructorBP', + expression: '"1234".parseIntPlusOne()', + expectedResult: '1235', + ); }); test('private field modification', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: '_field = 2', - expectedResult: '2'); + breakpointId: 'constructorBP', + expression: '_field = 2', + expectedResult: '2', + ); }); test('field modification', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'field = 2', - expectedResult: '2'); + breakpointId: 'constructorBP', + expression: 'field = 2', + expectedResult: '2', + ); }); test('private static field modification', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: '_staticField = 2', - expectedResult: '2'); + breakpointId: 'constructorBP', + expression: '_staticField = 2', + expectedResult: '2', + ); }); test('static field modification', () async { await driver.checkInFrame( - breakpointId: 'constructorBP', - expression: 'staticFieldD = 2', - expectedResult: '2'); + breakpointId: 'constructorBP', + expression: 'staticFieldD = 2', + expectedResult: '2', + ); }); }); group('async methods', () { test('compilation error', () async { await driver.checkInFrame( - breakpointId: 'asyncTestBP1', - expression: 'typo', - expectedError: "The getter 'typo' isn't defined for the class 'D'"); + breakpointId: 'asyncTestBP1', + expression: 'typo', + expectedError: "The getter 'typo' isn't defined for the class 'D'", + ); }); test('local', () async { await driver.checkInFrame( - breakpointId: 'asyncTestBP1', expression: 'x', expectedResult: '1'); + breakpointId: 'asyncTestBP1', + expression: 'x', + expectedResult: '1', + ); }); test('this', () async { await driver.checkInFrame( - breakpointId: 'asyncTestBP1', - expression: 'this', - expectedResult: allOf(contains('test.D.new'), - contains('Symbol(D.field): 5'), contains('Symbol(_field): 7'))); + breakpointId: 'asyncTestBP1', + expression: 'this', + expectedResult: allOf( + contains('test.D.new'), + contains('Symbol(D.field): 5'), + contains('Symbol(_field): 7'), + ), + ); }); - test('awaited method call', () async { - await driver.checkInFrame( + test( + 'awaited method call', + () async { + await driver.checkInFrame( breakpointId: 'asyncTestBP2', expression: 'd.asyncMethod(1).runtimeType.toString()', - expectedResult: '_Future<int>'); - }, skip: "'await' is not yet supported in expression evaluation."); + expectedResult: '_Future<int>', + ); + }, + skip: "'await' is not yet supported in expression evaluation.", + ); - test('awaited method call', () async { - await driver.checkInFrame( + test( + 'awaited method call', + () async { + await driver.checkInFrame( breakpointId: 'asyncTestBP2', expression: 'await d.asyncMethod(1)', - expectedResult: '58'); - }, skip: "'await' is not yet supported in expression evaluation."); + expectedResult: '58', + ); + }, + skip: "'await' is not yet supported in expression evaluation.", + ); }); group('closures', () { test('compilation error', () async { await driver.checkInFrame( - breakpointId: 'closuresTestBP', - expression: 'typo', - expectedError: "Undefined name 'typo'."); + breakpointId: 'closuresTestBP', + expression: 'typo', + expectedError: "Undefined name 'typo'.", + ); }); test('expression using captured variables', () async { await driver.checkInFrame( - breakpointId: 'closuresTestBP', - expression: r"'$y+$z'", - expectedResult: '3+0'); + breakpointId: 'closuresTestBP', + expression: r"'$y+$z'", + expectedResult: '3+0', + ); }); test('expression using uncaptured variables', () async { await driver.checkInFrame( - breakpointId: 'closuresTestBP', - expression: r"'$x+$y+$z'", - expectedResult: '15+3+0'); + breakpointId: 'closuresTestBP', + expression: r"'$x+$y+$z'", + expectedResult: '15+3+0', + ); }); }); group('method not already loading the types needed', () { test('call function not using type', () async { await driver.checkInFrame( - breakpointId: 'missingTypesTestBP', - expression: 'bar(p)', - expectedResult: '1'); + breakpointId: 'missingTypesTestBP', + expression: 'bar(p)', + expectedResult: '1', + ); }); test('call function using type', () async { await driver.checkInFrame( - breakpointId: 'missingTypesTestBP', - expression: "baz('\$p')", - expectedResult: '1'); + breakpointId: 'missingTypesTestBP', + expression: "baz('\$p')", + expectedResult: '1', + ); }); test('evaluate new const expression', () async { await driver.checkInFrame( - breakpointId: 'missingTypesTestBP', - expression: 'const MyClass(1)', - expectedResult: 'MyClass {Symbol(MyClass._t): 1}'); + breakpointId: 'missingTypesTestBP', + expression: 'const MyClass(1)', + expectedResult: 'MyClass {Symbol(MyClass._t): 1}', + ); }); - test('evaluate optimized const expression', () async { - await driver.checkInFrame( + test( + 'evaluate optimized const expression', + () async { + await driver.checkInFrame( breakpointId: 'missingTypesTestBP', expression: 't', - expectedResult: '1'); - }, - skip: 'Cannot compile constants optimized away by the frontend. ' - 'Issue: https://github.com/dart-lang/sdk/issues/41999'); + expectedResult: '1', + ); + }, + skip: + 'Cannot compile constants optimized away by the frontend. ' + 'Issue: https://github.com/dart-lang/sdk/issues/41999', + ); test('evaluate factory constructor call', () async { await driver.checkInFrame( - breakpointId: 'missingTypesTestBP', - expression: "Key('t')", - expectedResult: 'test.ValueKey.new {Symbol(ValueKey.value): t}'); + breakpointId: 'missingTypesTestBP', + expression: "Key('t')", + expectedResult: 'test.ValueKey.new {Symbol(ValueKey.value): t}', + ); }); test('evaluate const factory constructor call', () async { await driver.checkInFrame( - breakpointId: 'missingTypesTestBP', - expression: "const Key('t')", - expectedResult: 'ValueKey {Symbol(ValueKey.value): t}'); + breakpointId: 'missingTypesTestBP', + expression: "const Key('t')", + expectedResult: 'ValueKey {Symbol(ValueKey.value): t}', + ); }); }); @@ -1592,54 +1782,68 @@ // http://github.com/dart-lang/sdk/issues/55299 for details. test('expression using local & loop var', () async { await driver.checkInFrame( - breakpointId: 'forLoopTestBP', - expression: r'"$x + $i"', - expectedResult: '15 + 0'); + breakpointId: 'forLoopTestBP', + expression: r'"$x + $i"', + expectedResult: '15 + 0', + ); }); }); group('conditional:', () { test('(then) expression using local', () async { await driver.checkInFrame( - breakpointId: 'thenBP', expression: 'y', expectedResult: '3'); + breakpointId: 'thenBP', + expression: 'y', + expectedResult: '3', + ); }); test('(then) expression using local out of scope', () async { await driver.checkInFrame( - breakpointId: 'thenBP', - expression: 'z', - expectedError: "Error: Undefined name 'z'"); + breakpointId: 'thenBP', + expression: 'z', + expectedError: "Error: Undefined name 'z'", + ); }); test('(else) expression using local', () async { await driver.checkInFrame( - breakpointId: 'elseBP', expression: 'z', expectedResult: '4'); + breakpointId: 'elseBP', + expression: 'z', + expectedResult: '4', + ); }); test('(else) expression using local out of scope', () async { await driver.checkInFrame( - breakpointId: 'elseBP', - expression: 'y', - expectedError: "Error: Undefined name 'y'"); + breakpointId: 'elseBP', + expression: 'y', + expectedError: "Error: Undefined name 'y'", + ); }); test('(post) expression using local', () async { await driver.checkInFrame( - breakpointId: 'postBP', expression: 'x', expectedResult: '1'); + breakpointId: 'postBP', + expression: 'x', + expectedResult: '1', + ); }); test('(post) expression using local out of scope', () async { await driver.checkInFrame( - breakpointId: 'postBP', - expression: 'z', - expectedError: "Error: Undefined name 'z'"); + breakpointId: 'postBP', + expression: 'z', + expectedError: "Error: Undefined name 'z'", + ); }); test('(post) expression using local out of scope', () async { await driver.checkInFrame( - breakpointId: 'postBP', - expression: 'y', - expectedError: "Error: Undefined name 'y'"); + breakpointId: 'postBP', + expression: 'y', + expectedError: "Error: Undefined name 'y'", + ); }); }); @@ -1649,65 +1853,76 @@ // http://github.com/dart-lang/sdk/issues/55299 for details. test('expression loop variable', () async { await driver.checkInFrame( - breakpointId: 'iteratorLoopTestBP', - expression: 'e', - expectedResult: '1'); + breakpointId: 'iteratorLoopTestBP', + expression: 'e', + expectedResult: '1', + ); }); }); group('generic method', () { test('evaluate formals', () async { await driver.checkInFrame( - breakpointId: 'genericBP', - expression: "'\${a} \$b'", - expectedResult: '0 hi'); + breakpointId: 'genericBP', + expression: "'\${a} \$b'", + expectedResult: '0 hi', + ); }); test('evaluate class type parameters', () async { await driver.checkInFrame( - breakpointId: 'genericBP', - expression: "'\$T1'", - expectedResult: 'int'); + breakpointId: 'genericBP', + expression: "'\$T1'", + expectedResult: 'int', + ); }); test('evaluate method type parameters', () async { await driver.checkInFrame( - breakpointId: 'genericBP', - expression: "'\$T2'", - expectedResult: 'String'); + breakpointId: 'genericBP', + expression: "'\$T2'", + expectedResult: 'String', + ); }); }); group('interactions with module containers', () { - test('evaluation that non-destructively appends to the type container', - () async { - await driver.checkInFrame( + test( + 'evaluation that non-destructively appends to the type container', + () async { + await driver.checkInFrame( breakpointId: 'moduleContainersBP', expression: 'a is String', - expectedResult: 'false'); - }); + expectedResult: 'false', + ); + }, + ); test('evaluation that reuses the type container', () async { await driver.checkInFrame( - breakpointId: 'moduleContainersBP', - expression: 'a is int', - expectedResult: 'false'); + breakpointId: 'moduleContainersBP', + expression: 'a is int', + expectedResult: 'false', + ); }); test( - 'evaluation that non-destructively appends to the constant container', - () async { - await driver.checkInFrame( + 'evaluation that non-destructively appends to the constant container', + () async { + await driver.checkInFrame( breakpointId: 'moduleContainersBP', expression: 'const M2() == const M2()', - expectedResult: 'true'); - }); + expectedResult: 'true', + ); + }, + ); test('evaluation that properly canonicalizes constants', () async { await driver.checkInFrame( - breakpointId: 'moduleContainersBP', - expression: 'a == const M1()', - expectedResult: 'true'); + breakpointId: 'moduleContainersBP', + expression: 'a == const M1()', + expectedResult: 'true', + ); }); }); });
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart index 691b78f..97055a4 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
@@ -43,8 +43,12 @@ final TimeoutTracker tracker = TimeoutTracker(); ExpressionEvaluationTestDriver._( - this.chrome, this.chromeDir, this.connection, this.debugger, this.runtime) - : executionContext = ExecutionContext(runtime); + this.chrome, + this.chromeDir, + this.connection, + this.debugger, + this.runtime, + ) : executionContext = ExecutionContext(runtime); /// Initializes a Chrome browser instance, tab connection, and debugger. static Future<ExpressionEvaluationTestDriver> init() async { @@ -62,9 +66,11 @@ // accidentally start multiple instances. while (chrome == null && retries-- > 0) { try { - chrome = await browser.Chrome.startWithDebugPort(['about:blank'], - userDataDir: chromeDir.uri.toFilePath(), - headless: !Platform.isWindows); + chrome = await browser.Chrome.startWithDebugPort( + ['about:blank'], + userDataDir: chromeDir.uri.toFilePath(), + headless: !Platform.isWindows, + ); } catch (e) { if (retries == 0) rethrow; await Future.delayed(Duration(seconds: 5)); @@ -76,28 +82,42 @@ // Connect to the first 'normal' tab. var tab = await chrome.chromeConnection.getTab( - (tab) => !tab.isBackgroundPage && !tab.isChromeExtension, - retryFor: Duration(seconds: 5)); + (tab) => !tab.isBackgroundPage && !tab.isChromeExtension, + retryFor: Duration(seconds: 5), + ); if (tab == null) { throw Exception('Unable to connect to Chrome tab'); } - var connection = await tab.connect().timeout(Duration(seconds: 5), - onTimeout: (() => throw Exception('Unable to connect to WIP tab'))); + var connection = await tab.connect().timeout( + Duration(seconds: 5), + onTimeout: (() => throw Exception('Unable to connect to WIP tab')), + ); - await connection.page.enable().timeout(Duration(seconds: 5), - onTimeout: (() => throw Exception('Unable to enable WIP tab page'))); + await connection.page.enable().timeout( + Duration(seconds: 5), + onTimeout: (() => throw Exception('Unable to enable WIP tab page')), + ); var runtime = connection.runtime; - await runtime.enable().timeout(Duration(seconds: 5), - onTimeout: (() => throw Exception('Unable to enable WIP runtime'))); + await runtime.enable().timeout( + Duration(seconds: 5), + onTimeout: (() => throw Exception('Unable to enable WIP runtime')), + ); var debugger = connection.debugger; - await debugger.enable().timeout(Duration(seconds: 5), - onTimeout: (() => throw Exception('Unable to enable WIP debugger'))); + await debugger.enable().timeout( + Duration(seconds: 5), + onTimeout: (() => throw Exception('Unable to enable WIP debugger')), + ); return ExpressionEvaluationTestDriver._( - chrome, chromeDir, connection, debugger, runtime); + chrome, + chromeDir, + connection, + debugger, + runtime, + ); } /// Must be called when testing a new Dart program. @@ -109,11 +129,15 @@ String source, { Map<String, bool> experiments = const {}, String? partSource, - }) => - tracker._watch( - 'init-source', - () => _initSource(setup, source, - experiments: experiments, partSource: partSource)); + }) => tracker._watch( + 'init-source', + () => _initSource( + setup, + source, + experiments: experiments, + partSource: partSource, + ), + ); Future<void> _initSource( SetupCompilerOptions setup, @@ -164,37 +188,47 @@ '''); // Initialize DDC and the incremental compiler, then perform a full compile. - compiler = await TestExpressionCompiler.init(setup, - input: input, - output: output, - packages: packagesFile, - experiments: experiments); + compiler = await TestExpressionCompiler.init( + setup, + input: input, + output: output, + packages: packagesFile, + experiments: experiments, + ); htmlBootstrapper = testDir.uri.resolve('bootstrapper.html'); var bootstrapFile = File(htmlBootstrapper.toFilePath())..createSync(); var moduleName = compiler.metadata!.name; var mainLibraryName = libraryUriToImportName( - Uri.parse(compiler.metadataForLibraryUri(input).importUri)); + Uri.parse(compiler.metadataForLibraryUri(input).importUri), + ); var appName = p.relative( - p.withoutExtension(compiler.metadataForLibraryUri(input).importUri)); + p.withoutExtension(compiler.metadataForLibraryUri(input).importUri), + ); switch (setup.moduleFormat) { case ModuleFormat.ddc: - dartSdkPath = escaped(SetupCompilerOptions.buildRoot - .resolve(p.join( - 'gen', - 'utils', - 'ddc', - setup.canaryFeatures ? 'canary' : 'stable', - 'sdk', - 'ddc', - 'dart_sdk.js')) - .toFilePath()); + dartSdkPath = escaped( + SetupCompilerOptions.buildRoot + .resolve( + p.join( + 'gen', + 'utils', + 'ddc', + setup.canaryFeatures ? 'canary' : 'stable', + 'sdk', + 'ddc', + 'dart_sdk.js', + ), + ) + .toFilePath(), + ); if (!File(dartSdkPath).existsSync()) { throw Exception('Unable to find Dart SDK at $dartSdkPath'); } var dartLibraryPath = escaped( - p.join(ddcPath, 'lib', 'js', 'ddc', 'ddc_module_loader.js')); + p.join(ddcPath, 'lib', 'js', 'ddc', 'ddc_module_loader.js'), + ); var outputPath = output.toFilePath(); if (setup.emitLibraryBundle) { bootstrapFile.writeAsStringSync(''' @@ -236,25 +270,33 @@ '''); } case ModuleFormat.amd: - var dartSdkPathNoExtension = escaped(SetupCompilerOptions.buildRoot - .resolve(p.join( - 'gen', - 'utils', - 'ddc', - setup.canaryFeatures ? 'canary' : 'stable', - 'sdk', - 'amd', - 'dart_sdk')) - .toFilePath()); + var dartSdkPathNoExtension = escaped( + SetupCompilerOptions.buildRoot + .resolve( + p.join( + 'gen', + 'utils', + 'ddc', + setup.canaryFeatures ? 'canary' : 'stable', + 'sdk', + 'amd', + 'dart_sdk', + ), + ) + .toFilePath(), + ); dartSdkPath = '$dartSdkPathNoExtension.js'; if (!File(dartSdkPath).existsSync()) { throw Exception('Unable to find Dart SDK at $dartSdkPath'); } - var requirePath = escaped(SetupCompilerOptions.buildRoot - .resolve( - p.join('dart-sdk', 'lib', 'dev_compiler', 'amd', 'require.js')) - .toFilePath()); + var requirePath = escaped( + SetupCompilerOptions.buildRoot + .resolve( + p.join('dart-sdk', 'lib', 'dev_compiler', 'amd', 'require.js'), + ) + .toFilePath(), + ); var outputPath = escaped(p.withoutExtension(output.toFilePath())); bootstrapFile.writeAsStringSync(''' <script src='$requirePath'></script> @@ -290,8 +332,10 @@ '''); default: - throw Exception('Unsupported module format for SDK evaluation tests: ' - '${setup.moduleFormat}'); + throw Exception( + 'Unsupported module format for SDK evaluation tests: ' + '${setup.moduleFormat}', + ); } bootstrapSource = bootstrapFile.readAsStringSync(); await setBreakpointsActive(debugger, true); @@ -328,9 +372,11 @@ required Map<String, String> expectedScope, }) async { final actualScope = await getScope(breakpointId); - actualScope.removeWhere((key, value) => - _ddcTemporaryVariableRegExp.hasMatch(key) || - _ddcTemporaryTypeVariableRegExp.hasMatch(key)); + actualScope.removeWhere( + (key, value) => + _ddcTemporaryVariableRegExp.hasMatch(key) || + _ddcTemporaryTypeVariableRegExp.hasMatch(key), + ); expect(actualScope, expectedScope); } @@ -351,8 +397,9 @@ if (_bootstrapScript != null && _script != null) return; final bootstrapController = StreamController<wip.ScriptParsedEvent>(); final scriptController = StreamController<wip.ScriptParsedEvent>(); - final consoleSub = debugger.connection.runtime.onConsoleAPICalled - .listen((e) => printOnFailure('$e')); + final consoleSub = debugger.connection.runtime.onConsoleAPICalled.listen( + (e) => printOnFailure('$e'), + ); // Fail on exceptions in JS code. await debugger.setPauseOnExceptions(wip.PauseState.uncaught); @@ -375,27 +422,36 @@ // Navigate to the page that will load the application code. // Note: the bootstrapper does not invoke the application main, but // exposes a function that can be called to do so. - await connection.page.navigate('$htmlBootstrapper').timeout( - Duration(seconds: 5), - onTimeout: (() => throw Exception( - 'Unable to navigate to page bootstrap script: $htmlBootstrapper'))); + await connection.page + .navigate('$htmlBootstrapper') + .timeout( + Duration(seconds: 5), + onTimeout: (() => throw Exception( + 'Unable to navigate to page bootstrap script: $htmlBootstrapper', + )), + ); // Poll until both scripts are found, or timeout after a few seconds. _bootstrapScript = (await tracker._watch( - 'find-bootstrap-script', - () => bootstrapController.stream.first.timeout( - Duration(seconds: 10), - onTimeout: (() => throw Exception( - 'Unable to find bootstrap script corresponding to ' - '$htmlBootstrapper in ${debugger.scripts}.'))))) - .script; + 'find-bootstrap-script', + () => bootstrapController.stream.first.timeout( + Duration(seconds: 10), + onTimeout: (() => throw Exception( + 'Unable to find bootstrap script corresponding to ' + '$htmlBootstrapper in ${debugger.scripts}.', + )), + ), + )).script; _script = (await tracker._watch( - 'find-input-script', - () => scriptController.stream.first.timeout(Duration(seconds: 10), - onTimeout: (() => throw Exception( - 'Unable to find JS script corresponding to test file ' - '$output in ${debugger.scripts}.'))))) - .script; + 'find-input-script', + () => scriptController.stream.first.timeout( + Duration(seconds: 10), + onTimeout: (() => throw Exception( + 'Unable to find JS script corresponding to test file ' + '$output in ${debugger.scripts}.', + )), + ), + )).script; } finally { await scriptSub.cancel(); await consoleSub.cancel(); @@ -408,12 +464,14 @@ /// Uses the debugger API to trigger the execution of the app. Future<wip.RemoteObject> _scheduleMain() async { final context = await executionContext.id; - return runtime - .evaluate('scheduleMain()', contextId: context) - .catchError((Object e) { - printOnFailure(e is wip.ExceptionDetails - ? 'Exception when calling scheduleMain: ${e.json}!' - : 'Uncaught exception during scheduleMain: $e'); + return runtime.evaluate('scheduleMain()', contextId: context).catchError(( + Object e, + ) { + printOnFailure( + e is wip.ExceptionDetails + ? 'Exception when calling scheduleMain: ${e.json}!' + : 'Uncaught exception during scheduleMain: $e', + ); throw e; }); } @@ -423,20 +481,24 @@ /// /// Internally, this navigates to the bootstrapper page or ensures that the /// bootstrapper page has already been loaded. The page only loads code - /// without running the DDC app main method. Once the resouces are loaded we + /// without running the DDC app main method. Once the resources are loaded we /// wait until after the breakpoint is registered before scheduling a call to /// the app's main method. - Future<T> _onBreakpoint<T>(String breakpointId, - {required Future<T> Function(wip.DebuggerPausedEvent) onPause}) async { - final consoleSub = debugger.connection.runtime.onConsoleAPICalled - .listen((e) => printOnFailure('$e')); + Future<T> _onBreakpoint<T>( + String breakpointId, { + required Future<T> Function(wip.DebuggerPausedEvent) onPause, + }) async { + final consoleSub = debugger.connection.runtime.onConsoleAPICalled.listen( + (e) => printOnFailure('$e'), + ); // Used to reflect when [breakpointId] is hit. final breakpointCompleter = Completer<wip.DebuggerPausedEvent>(); final pauseSub = debugger.onPaused.listen((e) { if (e.reason == 'exception' || e.reason == 'assert') { - breakpointCompleter - .completeError('Uncaught exception in JS code: ${e.data}'); + breakpointCompleter.completeError( + 'Uncaught exception in JS code: ${e.data}', + ); throw Exception('Script failed while waiting for a breakpoint to hit.'); } breakpointCompleter.complete(e); @@ -449,18 +511,24 @@ var location = await _locationFromLine(line.value, line.key); var bp = await tracker._watch( - 'set-breakpoint', () => debugger.setBreakpoint(location)); + 'set-breakpoint', + () => debugger.setBreakpoint(location), + ); final atBreakpoint = breakpointCompleter.future; try { // Now that the breakpoint is set, the application can start running. unawaited(_scheduleMain()); final event = await tracker._watch( - 'pause-event-for-line', - () => atBreakpoint.timeout(Duration(seconds: 10), - onTimeout: () => throw Exception( - 'Unable to find JS pause event corresponding to line ' - '($line -> $location).'))); + 'pause-event-for-line', + () => atBreakpoint.timeout( + Duration(seconds: 10), + onTimeout: () => throw Exception( + 'Unable to find JS pause event corresponding to line ' + '($line -> $location).', + ), + ), + ); return await onPause(event); } finally { await pauseSub.cancel(); @@ -478,8 +546,9 @@ /// Load the script and run the [body] while the app is running. Future<T> _whileRunning<T>({required Future<T> Function() body}) async { - final consoleSub = debugger.connection.runtime.onConsoleAPICalled - .listen((e) => printOnFailure('$e')); + final consoleSub = debugger.connection.runtime.onConsoleAPICalled.listen( + (e) => printOnFailure('$e'), + ); await _loadScript(); try { @@ -491,11 +560,14 @@ } Future<Map<String, String>> getScope(String breakpointId) async { - return await _onBreakpoint(breakpointId, onPause: (event) async { - // Retrieve the call frame and its scope variables. - var frame = event.getCallFrames().first; - return await _collectScopeVariables(frame); - }); + return await _onBreakpoint( + breakpointId, + onPause: (event) async { + // Retrieve the call frame and its scope variables. + var frame = event.getCallFrames().first; + return await _collectScopeVariables(frame); + }, + ); } /// Evaluates a dart [expression] on a breakpoint. @@ -505,21 +577,23 @@ required String breakpointId, required String expression, }) async { - return await _onBreakpoint(breakpointId, onPause: (event) async { - var result = await _evaluateDartExpressionInFrame( - event, - expression, - ); - return await stringifyRemoteObject(result); - }); + return await _onBreakpoint( + breakpointId, + onPause: (event) async { + var result = await _evaluateDartExpressionInFrame(event, expression); + return await stringifyRemoteObject(result); + }, + ); } /// Evaluates a dart [expression] while the app is running. Future<String> evaluateDartExpression({required String expression}) async { - return await _whileRunning(body: () async { - var result = await _evaluateDartExpression(expression); - return await stringifyRemoteObject(result); - }); + return await _whileRunning( + body: () async { + var result = await _evaluateDartExpression(expression); + return await stringifyRemoteObject(result); + }, + ); } /// Given a [remoteObject] and only one of [expectedError] and @@ -551,8 +625,10 @@ 'Unexpected expression evaluation success:\n${remoteObject.json}', ); if (stringifyResult) { - expect(await stringifyRemoteObject(remoteObject), - _matches(expectedResult!)); + expect( + await stringifyRemoteObject(remoteObject), + _matches(expectedResult!), + ); } else { expect(remoteObject.value, _matches(equals(expectedResult!))); } @@ -576,15 +652,21 @@ dynamic expectedError, dynamic expectedResult, }) async { - assert(expectedError == null || expectedResult == null, - 'Cannot expect both an error and result.'); + assert( + expectedError == null || expectedResult == null, + 'Cannot expect both an error and result.', + ); - return await _onBreakpoint(breakpointId, onPause: (event) async { - await _matchRemoteObject( + return await _onBreakpoint( + breakpointId, + onPause: (event) async { + await _matchRemoteObject( remoteObject: await _evaluateJsExpression(event, expression), expectedError: expectedError, - expectedResult: expectedResult); - }); + expectedResult: expectedResult, + ); + }, + ); } /// Evaluates a dart [expression] on a breakpoint and validates result. @@ -593,78 +675,91 @@ /// [expression] is a dart expression. /// [expectedResult] is the JSON for the returned remote object. /// [expectedError] is the error string if the error is expected. - Future<void> checkInFrame( - {required String breakpointId, - required String expression, - dynamic expectedError, - dynamic expectedResult}) => - tracker._watch( - 'check-in-frame', - () => _checkInFrame( - breakpointId: breakpointId, - expression: expression, - expectedError: expectedError, - expectedResult: expectedResult)); + Future<void> checkInFrame({ + required String breakpointId, + required String expression, + dynamic expectedError, + dynamic expectedResult, + }) => tracker._watch( + 'check-in-frame', + () => _checkInFrame( + breakpointId: breakpointId, + expression: expression, + expectedError: expectedError, + expectedResult: expectedResult, + ), + ); - Future<void> _checkInFrame( - {required String breakpointId, - required String expression, - dynamic expectedError, - dynamic expectedResult}) async { - assert(expectedError == null || expectedResult == null, - 'Cannot expect both an error and result.'); + Future<void> _checkInFrame({ + required String breakpointId, + required String expression, + dynamic expectedError, + dynamic expectedResult, + }) async { + assert( + expectedError == null || expectedResult == null, + 'Cannot expect both an error and result.', + ); - return await _onBreakpoint(breakpointId, onPause: (event) async { - await _matchRemoteObject( - remoteObject: await _evaluateDartExpressionInFrame( - event, - expression, - ), + return await _onBreakpoint( + breakpointId, + onPause: (event) async { + await _matchRemoteObject( + remoteObject: await _evaluateDartExpressionInFrame(event, expression), expectedError: expectedError, expectedResult: expectedResult, - stringifyResult: true); - }); + stringifyResult: true, + ); + }, + ); } /// Evaluates a dart [expression] under the scope of [libraryUri] without /// a breakpoint and validates the result. /// - /// When [libraryUri] is ommitted, the expression is evaluated in the [input] + /// When [libraryUri] is omitted, the expression is evaluated in the [input] /// library. /// /// [expectedResult] is the JSON for the returned remote object. /// [expectedError] is the error string if the error is expected. - Future<void> check( - {required String expression, - Uri? libraryUri, - dynamic expectedError, - dynamic expectedResult}) async { - assert(expectedError == null || expectedResult == null, - 'Cannot expect both an error and result.'); + Future<void> check({ + required String expression, + Uri? libraryUri, + dynamic expectedError, + dynamic expectedResult, + }) async { + assert( + expectedError == null || expectedResult == null, + 'Cannot expect both an error and result.', + ); - return await _whileRunning(body: () async { - var evalResult = - await _evaluateDartExpression(expression, libraryUri: libraryUri); + return await _whileRunning( + body: () async { + var evalResult = await _evaluateDartExpression( + expression, + libraryUri: libraryUri, + ); - var error = evalResult.json['error']; - if (error != null) { - expect( - expectedError, - isNotNull, - reason: 'Unexpected expression evaluation failure:\n$error', - ); - expect(error, _matches(expectedError!)); - } else { - expect( - expectedResult, - isNotNull, - reason: - 'Unexpected expression evaluation success:\n${evalResult.json}', - ); - var actual = await stringifyRemoteObject(evalResult); - expect(actual, _matches(expectedResult!)); - } - }); + var error = evalResult.json['error']; + if (error != null) { + expect( + expectedError, + isNotNull, + reason: 'Unexpected expression evaluation failure:\n$error', + ); + expect(error, _matches(expectedError!)); + } else { + expect( + expectedResult, + isNotNull, + reason: + 'Unexpected expression evaluation success:\n${evalResult.json}', + ); + var actual = await stringifyRemoteObject(evalResult); + expect(actual, _matches(expectedResult!)); + } + }, + ); } Future<wip.RemoteObject> _evaluateJsExpression( @@ -681,13 +776,15 @@ var loadModule = setup.moduleFormat == ModuleFormat.amd ? 'require' : 'dart_library.import'; - jsExpressionBody = ''' + jsExpressionBody = + ''' var sdk = $loadModule('dart_sdk'); var dart = sdk.dart; '''; } - var jsExpression = ''' + var jsExpression = + ''' (function () { $jsExpressionBody return $expression; @@ -706,7 +803,9 @@ } Future<TestCompilationResult> _compileDartExpressionInFrame( - wip.WipCallFrame frame, String expression) async { + wip.WipCallFrame frame, + String expression, + ) async { // Retrieve the call frame and its scope variables. var scope = await _collectScopeVariables(frame); var searchLine = frame.location.lineNumber; @@ -740,8 +839,10 @@ } } if (best == null || best.sourceLine == null || best.sourceColumn == null) { - throw StateError('Unable to find the matching dart line and column ' - ' for where the javascript paused.'); + throw StateError( + 'Unable to find the matching dart line and column ' + ' for where the javascript paused.', + ); } final bestUrl = compiler.sourceMap.urls[best.sourceUrlId!]; @@ -766,7 +867,9 @@ } Future<TestCompilationResult> _compileDartExpression( - String expression, Uri? libraryUri) async { + String expression, + Uri? libraryUri, + ) async { // Perform an incremental compile. return await compiler.compileExpression( libraryUri: libraryUri ?? input, @@ -783,10 +886,7 @@ bool returnByValue = false, }) async { var frame = event.getCallFrames().first; - var result = await _compileDartExpressionInFrame( - frame, - expression, - ); + var result = await _compileDartExpressionInFrame(frame, expression); if (!result.isSuccess) { return _createCompilationError(result); @@ -858,13 +958,16 @@ return 'null'; } try { - var properties = - await connection.runtime.getProperties(obj, ownProperties: true); + var properties = await connection.runtime.getProperties( + obj, + ownProperties: true, + ); var filteredProps = <String, String?>{}; for (var prop in properties) { if (prop.value != null && prop.name != '__proto__') { - filteredProps[prop.name] = - await stringifyRemoteObject(prop.value!); + filteredProps[prop.name] = await stringifyRemoteObject( + prop.value!, + ); } } str = '${obj.description} $filteredProps'; @@ -881,12 +984,15 @@ /// /// Adapted from webdev/dwds/lib/src/services/expression_evaluator.dart. Future<Map<String, String>> _collectScopeVariables( - wip.WipCallFrame frame) async { + wip.WipCallFrame frame, + ) async { var jsScope = <String, String>{}; for (var scope in filterScopes(frame)) { - var response = await connection.runtime - .getProperties(scope.object, ownProperties: true); + var response = await connection.runtime.getProperties( + scope.object, + ownProperties: true, + ); for (var prop in response) { var propKey = prop.name; var propValue = '${prop.value?.value}'; @@ -941,7 +1047,8 @@ return MapEntry(htmlBootstrapper, lineNumber + 1); } throw StateError( - 'Unable to find breakpoint in $input with id: $breakpointId'); + 'Unable to find breakpoint in $input with id: $breakpointId', + ); } /// Finds the 0-indexed line number in [source] for the given breakpoint id. @@ -973,7 +1080,8 @@ } } throw StateError( - 'Unable to extract WIP Location from ${script.url} for line $line.'); + 'Unable to extract WIP Location from ${script.url} for line $line.', + ); } } @@ -1024,8 +1132,9 @@ final contextController = StreamController<int>(); _runtime.onExecutionContextsCleared.listen((_) => _id = null); _runtime.onExecutionContextDestroyed.listen((_) => _id = null); - _runtime.onExecutionContextCreated - .listen((e) => contextController.add(e.id)); + _runtime.onExecutionContextCreated.listen( + (e) => contextController.add(e.id), + ); _contexts = StreamQueue(contextController.stream); } } @@ -1037,8 +1146,8 @@ List<wip.WipScope> filterScopes(wip.WipCallFrame frame) { var scopes = frame.getScopeChain().toList(); // Remove outer scopes up to and including the Dart SDK. - while ( - scopes.isNotEmpty && !(scopes.last.name?.startsWith('load__') ?? false)) { + while (scopes.isNotEmpty && + !(scopes.last.name?.startsWith('load__') ?? false)) { scopes.removeLast(); } if (scopes.isNotEmpty) scopes.removeLast(); @@ -1048,10 +1157,12 @@ String escaped(String path) => path.replaceAll('\\', '\\\\'); Future setBreakpointsActive(wip.WipDebugger debugger, bool active) async { - await debugger.sendCommand('Debugger.setBreakpointsActive', params: { - 'active': active - }).timeout(Duration(seconds: 5), - onTimeout: (() => throw Exception('Unable to set breakpoint activity'))); + await debugger + .sendCommand('Debugger.setBreakpointsActive', params: {'active': active}) + .timeout( + Duration(seconds: 5), + onTimeout: (() => throw Exception('Unable to set breakpoint activity')), + ); } /// The regexes used in dwds to filter out temp variables. @@ -1067,7 +1178,7 @@ /// /// A few steps in the test driver need to wait for a response from the browser. /// These are set up with a timeout of usually 5 seconds, but the total time may -/// vary by machine and architecture. Occationally tests fail with flaky +/// vary by machine and architecture. Occasionally tests fail with flaky /// failures due to a timeout that is too short. /// /// We use this class to help log information from flaky failures that can @@ -1091,7 +1202,7 @@ /// Record under [key] a single event that took [milliseconds]. /// - /// This makes an incremental update to the aggreagate average, max, and count + /// This makes an incremental update to the aggregate average, max, and count /// values in [_data]. void _addOneRecord(String key, int milliseconds) { (_data[key] ??= []).add(milliseconds); @@ -1108,12 +1219,14 @@ final p50 = values[(values.length * 0.5).toInt()]; final p90 = values[(values.length * 0.9).toInt()]; final average = sum ~/ total; - print('$key: ' - '${average}ms (avg), ' - '${p50}ms (p50), ' - '${p90}ms (p90), ' - '${max}ms (max), ' - '$total (total)'); + print( + '$key: ' + '${average}ms (avg), ' + '${p50}ms (p50), ' + '${p90}ms (p90), ' + '${max}ms (max), ' + '$total (total)', + ); }); } }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_suite.dart index 20e48b2..c3b208b 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_suite.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_suite.dart
@@ -51,8 +51,12 @@ } Future<TestExpressionCompiler> createCompiler() => - TestExpressionCompiler.init(setup, - input: input, output: output, packages: packages); + TestExpressionCompiler.init( + setup, + input: input, + output: output, + packages: packages, + ); Future<TestCompilationResult> compile({ required TestExpressionCompiler compiler, @@ -60,11 +64,12 @@ required String expression, }) async { return compiler.compileExpression( - libraryUri: input, - line: line, - column: 1, - scope: scope, - expression: expression); + libraryUri: input, + line: line, + column: 1, + scope: scope, + expression: expression, + ); } void checkResult( @@ -76,10 +81,11 @@ var message = success ? expectedResult! : expectedError; expect( - result, - const TypeMatcher<TestCompilationResult>() - .having((r) => r.result!, 'result', _matches(message)) - .having((r) => r.isSuccess, 'isSuccess', success)); + result, + const TypeMatcher<TestCompilationResult>() + .having((r) => r.result!, 'result', _matches(message)) + .having((r) => r.isSuccess, 'isSuccess', success), + ); } Future<void> check({ @@ -90,11 +96,17 @@ dynamic expectedResult, }) async { compiler ??= await createCompiler(); - var result = - await compile(compiler: compiler, scope: scope, expression: expression); + var result = await compile( + compiler: compiler, + scope: scope, + expression: expression, + ); - checkResult(result, - expectedError: expectedError, expectedResult: expectedResult); + checkResult( + result, + expectedError: expectedError, + expectedResult: expectedResult, + ); } Matcher _matches(dynamic matcher) {
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart index e98f905..5d8c7b6 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -11,10 +11,7 @@ void main(List<String> args) { for (var moduleFormat in [ModuleFormat.amd, ModuleFormat.ddc]) { group('Module format: $moduleFormat |', () { - runTests(SetupCompilerOptions( - moduleFormat: moduleFormat, - args: args, - )); + runTests(SetupCompilerOptions(moduleFormat: moduleFormat, args: args)); }); } } @@ -43,24 +40,27 @@ test('successful expression compilations', () async { var compiler = await driver.createCompiler(); await driver.check( - compiler: compiler, - scope: <String, String>{}, - expression: 'true', - expectedResult: contains('return true;')); + compiler: compiler, + scope: <String, String>{}, + expression: 'true', + expectedResult: contains('return true;'), + ); await driver.check( - compiler: compiler, - scope: <String, String>{}, - expression: 'false', - expectedResult: contains('return false;')); + compiler: compiler, + scope: <String, String>{}, + expression: 'false', + expectedResult: contains('return false;'), + ); }); test('some successful expression compilations', () async { var compiler = await driver.createCompiler(); await driver.check( - compiler: compiler, - scope: <String, String>{}, - expression: 'true', - expectedResult: contains('return true;')); + compiler: compiler, + scope: <String, String>{}, + expression: 'true', + expectedResult: contains('return true;'), + ); await driver.check( compiler: compiler, scope: <String, String>{}, @@ -68,10 +68,11 @@ expectedError: "Undefined name 'blah'", ); await driver.check( - compiler: compiler, - scope: <String, String>{}, - expression: 'false', - expectedResult: contains('return false;')); + compiler: compiler, + scope: <String, String>{}, + expression: 'false', + expectedResult: contains('return false;'), + ); }); test('failing expression compilations', () async { @@ -120,24 +121,29 @@ test('expression referencing unnamed import', () async { await driver.check( - scope: <String, String>{}, - expression: 'Directory.systemTemp', - expectedResult: contains('return io.Directory.systemTemp;')); + scope: <String, String>{}, + expression: 'Directory.systemTemp', + expectedResult: contains('return io.Directory.systemTemp;'), + ); }); test('expression referencing named import', () async { await driver.check( - scope: <String, String>{}, - expression: 'p.Directory.systemTemp', - expectedResult: contains('return io.Directory.systemTemp;')); + scope: <String, String>{}, + expression: 'p.Directory.systemTemp', + expectedResult: contains('return io.Directory.systemTemp;'), + ); }); - test('expression referencing another library with the same named import', - () async { - await driver.check( + test( + 'expression referencing another library with the same named import', + () async { + await driver.check( scope: <String, String>{}, expression: 'p.utf8.decoder', - expectedResult: contains('return convert.utf8.decoder;')); - }); + expectedResult: contains('return convert.utf8.decoder;'), + ); + }, + ); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_amd_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_amd_test.dart index 1a54fe3..210198c 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_amd_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_amd_test.dart
@@ -13,8 +13,10 @@ var debug = false; group('amd module format -', () { - var setup = - SetupCompilerOptions(moduleFormat: ModuleFormat.amd, args: args); + var setup = SetupCompilerOptions( + moduleFormat: ModuleFormat.amd, + args: args, + ); runTests(setup, verbose: debug); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_ddc_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_ddc_test.dart index b7ab7b4..c9c7a12 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_ddc_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_ddc_test.dart
@@ -13,8 +13,10 @@ var debug = false; group('ddc module format -', () { - var setup = - SetupCompilerOptions(moduleFormat: ModuleFormat.ddc, args: args); + var setup = SetupCompilerOptions( + moduleFormat: ModuleFormat.ddc, + args: args, + ); runTests(setup, verbose: debug); }); }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_shared.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_shared.dart index 4d5ccb8..45b9180 100644 --- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_shared.dart +++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_worker_shared.dart
@@ -40,32 +40,30 @@ test('reports failure to consumer', () async { expect( - receivePort, - emitsInOrder([ - equals(isA<SendPort>()), - equals({ - 'succeeded': false, - 'stackTrace': isNotNull, - 'exception': contains('Could not load SDK component'), - }), - ])); + receivePort, + emitsInOrder([ + equals(isA<SendPort>()), + equals({ + 'succeeded': false, + 'stackTrace': isNotNull, + 'exception': contains('Could not load SDK component'), + }), + ]), + ); try { var badPath = 'file:///path/does/not/exist'; - await ExpressionCompilerWorker.createAndStart( - [ - '--libraries-file', - badPath, - '--dart-sdk-summary', - badPath, - '--module-format', - setup.moduleFormat.name, - if (setup.enableAsserts) '--enable-asserts', - if (setup.canaryFeatures) '--canary', - if (verbose) '--verbose', - ], - sendPort: receivePort.sendPort, - ); + await ExpressionCompilerWorker.createAndStart([ + '--libraries-file', + badPath, + '--dart-sdk-summary', + badPath, + '--module-format', + setup.moduleFormat.name, + if (setup.enableAsserts) '--enable-asserts', + if (setup.canaryFeatures) '--canary', + if (verbose) '--verbose', + ], sendPort: receivePort.sendPort); } catch (e) { throwsA(contains('Could not load SDK component')); } @@ -78,7 +76,8 @@ group('reading assets using multiroot file system - ', () { runExpressionCompilationTests( - MultiRootFileSystemTestDriver(setup, verbose)); + MultiRootFileSystemTestDriver(setup, verbose), + ); }); group('reading assets using asset file system -', () { @@ -123,20 +122,21 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': - stringContainsInOrder(['developer', 'postEvent']), - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': stringContainsInOrder([ + 'developer', + 'postEvent', + ]), + }), + ]), + ); }); test('can compile library level expressions in sdk 1-based', () { @@ -158,20 +158,21 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': - stringContainsInOrder(['developer', 'postEvent']), - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': stringContainsInOrder([ + 'developer', + 'postEvent', + ]), + }), + ]), + ); }); test('cannot compile scoped expressions in sdk', () { @@ -196,24 +197,24 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - // When support is added, we should expect to see: - // 'succeeded': true, - // 'errors': isEmpty, - // 'warnings': isEmpty, - // 'infos': isEmpty, - // 'compiledProcedure': contains('return other;'), - equals({ - 'succeeded': false, - 'exception': contains( - 'Expression compilation inside SDK is not supported yet'), - 'stackTrace': isNotNull, - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + // When support is added, we should expect to see: + // 'succeeded': true, + // 'errors': isEmpty, + // 'warnings': isEmpty, + // 'infos': isEmpty, + // 'compiledProcedure': contains('return other;'), + equals({ + 'succeeded': false, + 'exception': contains( + 'Expression compilation inside SDK is not supported yet', + ), + 'stackTrace': isNotNull, + }), + ]), + ); }); test('can compile expressions in a library', () { @@ -234,54 +235,54 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + ]), + ); }); - test('compile expressions include "dart.library..." environment defines.', - () { - driver.requestController.add({ - 'command': 'UpdateDeps', - 'inputs': driver.inputs, - }); + test( + 'compile expressions include "dart.library..." environment defines.', + () { + driver.requestController.add({ + 'command': 'UpdateDeps', + 'inputs': driver.inputs, + }); - driver.requestController.add({ - 'command': 'CompileExpression', - 'expression': 'const bool.fromEnvironment("dart.library.html")', - 'line': 5, - 'column': 1, - 'jsModules': {}, - 'jsScope': {'formal': 'formal'}, - 'libraryUri': driver.config.getModule('testModule').libraryUris.first, - 'moduleName': driver.config.getModule('testModule').moduleName, - }); + driver.requestController.add({ + 'command': 'CompileExpression', + 'expression': 'const bool.fromEnvironment("dart.library.html")', + 'line': 5, + 'column': 1, + 'jsModules': {}, + 'jsScope': {'formal': 'formal'}, + 'libraryUri': driver.config.getModule('testModule').libraryUris.first, + 'moduleName': driver.config.getModule('testModule').moduleName, + }); - expect( + expect( driver.responseController.stream, emitsInOrder([ - equals({ - 'succeeded': true, - }), + equals({'succeeded': true}), equals({ 'succeeded': true, 'errors': isEmpty, 'warnings': isEmpty, 'infos': isEmpty, 'compiledProcedure': contains('true'), - }) - ])); - }); + }), + ]), + ); + }, + ); test('can compile expressions in main', () { driver.requestController.add({ @@ -301,19 +302,18 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return count;'), - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return count;'), + }), + ]), + ); }); test('can compile expressions in main (extension method)', () { @@ -334,19 +334,18 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return ret;'), - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return ret;'), + }), + ]), + ); }); test('can compile transitive expressions in main', () { @@ -367,20 +366,20 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': matches( - r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)'), - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': matches( + r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)', + ), + }), + ]), + ); }); test('can compile expressions in non-strongly-connected components', () { @@ -401,19 +400,18 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + ]), + ); }); test('can compile expressions in strongly connected components', () { @@ -434,19 +432,18 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + ]), + ); }); test('can compile series of expressions in various libraries', () { @@ -522,56 +519,57 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': matches( - r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': - matches(r'test_library[\$]?\.B\.new\(\)\.printNumber\(\)'), - }) - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': matches( + r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)', + ), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': matches( + r'test_library[\$]?\.B\.new\(\)\.printNumber\(\)', + ), + }), + ]), + ); }); test('can compile after dependency update', () { @@ -641,53 +639,53 @@ }); expect( - driver.responseController.stream, - emitsInOrder([ - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': matches( - r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': - matches(r'test_library[\$]?\.B\.new\(\)\.printNumber\(\)'), - }), - equals({ - 'succeeded': true, - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': matches( - r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)'), - }), - equals({ - 'succeeded': true, - 'errors': isEmpty, - 'warnings': isEmpty, - 'infos': isEmpty, - 'compiledProcedure': contains('return formal;'), - }), - ])); + driver.responseController.stream, + emitsInOrder([ + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': matches( + r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)', + ), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': matches( + r'test_library[\$]?\.B\.new\(\)\.printNumber\(\)', + ), + }), + equals({'succeeded': true}), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': matches( + r'new test_library[\$]?\.B\.new\(\)\.c\(\)\.getNumber\(\)', + ), + }), + equals({ + 'succeeded': true, + 'errors': isEmpty, + 'warnings': isEmpty, + 'infos': isEmpty, + 'compiledProcedure': contains('return formal;'), + }), + ]), + ); }); }); } @@ -738,61 +736,66 @@ void initialize() { final testModule4 = ModuleConfiguration( - root: root, - outputDir: outputDir, - moduleName: 'packages/_testPackage/test_library4', - libraryUris: [ - 'package:_testPackage/test_library7.dart', - 'package:_testPackage/test_library6.dart', - ], - dependencies: [], - jsFileName: 'test_library4.js', - fullDillFileName: 'test_library4.full.dill', - summaryDillFileName: 'test_library4.dill'); + root: root, + outputDir: outputDir, + moduleName: 'packages/_testPackage/test_library4', + libraryUris: [ + 'package:_testPackage/test_library7.dart', + 'package:_testPackage/test_library6.dart', + ], + dependencies: [], + jsFileName: 'test_library4.js', + fullDillFileName: 'test_library4.full.dill', + summaryDillFileName: 'test_library4.dill', + ); final testModule3 = ModuleConfiguration( - root: root, - outputDir: outputDir, - moduleName: 'packages/_testPackage/test_library3', - libraryUris: [ - 'package:_testPackage/test_library5.dart', - 'package:_testPackage/test_library4.dart', - 'package:_testPackage/test_library3.dart', - ], - dependencies: [], - jsFileName: 'test_library3.js', - fullDillFileName: 'test_library3.full.dill', - summaryDillFileName: 'test_library3.dill'); + root: root, + outputDir: outputDir, + moduleName: 'packages/_testPackage/test_library3', + libraryUris: [ + 'package:_testPackage/test_library5.dart', + 'package:_testPackage/test_library4.dart', + 'package:_testPackage/test_library3.dart', + ], + dependencies: [], + jsFileName: 'test_library3.js', + fullDillFileName: 'test_library3.full.dill', + summaryDillFileName: 'test_library3.dill', + ); final testModule2 = ModuleConfiguration( - root: root, - outputDir: outputDir, - moduleName: 'packages/_testPackage/test_library2', - libraryUris: ['package:_testPackage/test_library2.dart'], - dependencies: [], - jsFileName: 'test_library2.js', - fullDillFileName: 'test_library2.full.dill', - summaryDillFileName: 'test_library2.dill'); + root: root, + outputDir: outputDir, + moduleName: 'packages/_testPackage/test_library2', + libraryUris: ['package:_testPackage/test_library2.dart'], + dependencies: [], + jsFileName: 'test_library2.js', + fullDillFileName: 'test_library2.full.dill', + summaryDillFileName: 'test_library2.dill', + ); final testModule = ModuleConfiguration( - root: root, - outputDir: outputDir, - moduleName: 'packages/_testPackage/test_library', - libraryUris: ['package:_testPackage/test_library.dart'], - dependencies: [testModule2], - jsFileName: 'test_library.js', - fullDillFileName: 'test_library.full.dill', - summaryDillFileName: 'test_library.dill'); + root: root, + outputDir: outputDir, + moduleName: 'packages/_testPackage/test_library', + libraryUris: ['package:_testPackage/test_library.dart'], + dependencies: [testModule2], + jsFileName: 'test_library.js', + fullDillFileName: 'test_library.full.dill', + summaryDillFileName: 'test_library.dill', + ); final mainModule = ModuleConfiguration( - root: root, - outputDir: outputDir, - moduleName: 'packages/_testPackage/main', - libraryUris: ['org-dartlang-app:/lib/main.dart'], - dependencies: [testModule3, testModule2, testModule], - jsFileName: 'main.js', - fullDillFileName: 'main.full.dill', - summaryDillFileName: 'main.dill'); + root: root, + outputDir: outputDir, + moduleName: 'packages/_testPackage/main', + libraryUris: ['org-dartlang-app:/lib/main.dart'], + dependencies: [testModule3, testModule2, testModule], + jsFileName: 'main.js', + fullDillFileName: 'main.full.dill', + summaryDillFileName: 'main.dill', + ); modules = { 'testModule4': testModule4, @@ -813,34 +816,34 @@ Uri get librariesPath => sdkRoot.resolve('lib/libraries.json'); List get inputUris => [ - for (var module in modules.values) ...[ - { - 'path': '${module.multiRootFullDillUri}', - 'summaryPath': '${module.multiRootSummaryUri}', - 'moduleName': module.moduleName - }, - ] - ]; + for (var module in modules.values) ...[ + { + 'path': '${module.multiRootFullDillUri}', + 'summaryPath': '${module.multiRootSummaryUri}', + 'moduleName': module.moduleName, + }, + ], + ]; List get inputRelativeUris => [ - for (var module in modules.values) ...[ - { - 'path': '${module.multiRootFullDillUri}', - 'summaryPath': '${module.multiRootSummaryUri}', - 'moduleName': module.moduleName - }, - ] - ]; + for (var module in modules.values) ...[ + { + 'path': '${module.multiRootFullDillUri}', + 'summaryPath': '${module.multiRootSummaryUri}', + 'moduleName': module.moduleName, + }, + ], + ]; List get inputPaths => [ - for (var module in modules.values) ...[ - { - 'path': module.fullDillPath, - 'summaryPath': module.summaryDillPath, - 'moduleName': module.moduleName - }, - ] - ]; + for (var module in modules.values) ...[ + { + 'path': module.fullDillPath, + 'summaryPath': module.summaryDillPath, + 'moduleName': module.moduleName, + }, + ], + ]; ModuleConfiguration getModule(String name) => modules[name]!; @@ -1098,8 +1101,9 @@ @override Future<void> start() async { inputs = config.inputUris; - var fileSystem = MultiRootFileSystem( - 'org-dartlang-app', [tempDir.uri], StandardFileSystem.instance); + var fileSystem = MultiRootFileSystem('org-dartlang-app', [ + tempDir.uri, + ], StandardFileSystem.instance); assetFileSystem = fileSystem; } } @@ -1113,8 +1117,9 @@ @override Future<void> start() async { inputs = config.inputRelativeUris; - var fileSystem = MultiRootFileSystem( - 'org-dartlang-app', [tempDir.uri], StandardFileSystem.instance); + var fileSystem = MultiRootFileSystem('org-dartlang-app', [ + tempDir.uri, + ], StandardFileSystem.instance); port = await findUnusedPort(); server = TestAssetServer(fileSystem); assetFileSystem = AssetFileSystem(fileSystem, 'localhost', '$port'); @@ -1152,8 +1157,10 @@ 'content-length': '${contents.length}', ...request.headers, }; - return Response.ok(request.method == 'GET' ? contents : null, - headers: headers); + return Response.ok( + request.method == 'GET' ? contents : null, + headers: headers, + ); } } return Response.notFound(path); @@ -1178,8 +1185,9 @@ final TestProjectConfiguration config; final bool verbose; static final dart = Platform.resolvedExecutable; - static final sdkPath = - computePlatformBinariesLocation(forceBuildDir: true).toFilePath(); + static final sdkPath = computePlatformBinariesLocation( + forceBuildDir: true, + ).toFilePath(); static var dartExecutable = p.join( sdkPath, 'dart-sdk', @@ -1187,9 +1195,19 @@ Platform.isWindows ? 'dartaotruntime.exe' : 'dartaotruntime', ); static var dartdevc = p.join( - sdkPath, 'dart-sdk', 'bin', 'snapshots', 'dartdevc_aot.dart.snapshot'); - static var kernelWorker = p.join(sdkPath, 'dart-sdk', 'bin', 'snapshots', - 'kernel_worker_aot.dart.snapshot'); + sdkPath, + 'dart-sdk', + 'bin', + 'snapshots', + 'dartdevc_aot.dart.snapshot', + ); + static var kernelWorker = p.join( + sdkPath, + 'dart-sdk', + 'bin', + 'snapshots', + 'kernel_worker_aot.dart.snapshot', + ); DDCKernelGenerator(this.config, this.verbose); @@ -1197,23 +1215,32 @@ var exitCode = 0; if (!File(dartdevc).existsSync()) { exitCode = 1; - expect(exitCode, 0, - reason: 'Unable to locate snapshot for compiler $dartdevc'); + expect( + exitCode, + 0, + reason: 'Unable to locate snapshot for compiler $dartdevc', + ); } Directory.fromUri(config.outputPath).createSync(); // generate summaries for (var module in config.modules.values) { exitCode = await _generateSummary(module); - expect(exitCode, 0, - reason: 'Failed to generate summary dill for ${module.moduleName}'); + expect( + exitCode, + 0, + reason: 'Failed to generate summary dill for ${module.moduleName}', + ); } // generate full dill for (var module in config.modules.values) { exitCode = await _generateFullDill(module); - expect(exitCode, 0, - reason: 'Failed to generate full dill for ${module.moduleName}'); + expect( + exitCode, + 0, + reason: 'Failed to generate full dill for ${module.moduleName}', + ); } return exitCode; } @@ -1246,7 +1273,7 @@ ...module.libraryUris, for (var dependency in module.dependencies) ...[ '--summary', - '${dependency.multiRootSummaryUri}=${dependency.moduleName}' + '${dependency.multiRootSummaryUri}=${dependency.moduleName}', ], '-o', module.jsUri.toFilePath(), @@ -1271,20 +1298,29 @@ } } -Future<int> runProcess(String command, List<String> args, - String workingDirectory, bool verbose) async { +Future<int> runProcess( + String command, + List<String> args, + String workingDirectory, + bool verbose, +) async { if (verbose) { - print('Running command in $workingDirectory:' - '\n\t $command ${args.join(' ')}, '); + print( + 'Running command in $workingDirectory:' + '\n\t $command ${args.join(' ')}, ', + ); } var process = - await Process.start(command, args, workingDirectory: workingDirectory) - .then((Process process) { - process - ..stdout.transform(utf8.decoder).listen(stdout.write) - ..stderr.transform(utf8.decoder).listen(stderr.write); - return process; - }); + await Process.start( + command, + args, + workingDirectory: workingDirectory, + ).then((Process process) { + process + ..stdout.transform(utf8.decoder).listen(stdout.write) + ..stderr.transform(utf8.decoder).listen(stderr.write); + return process; + }); return await process.exitCode; }
diff --git a/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart b/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart index 0782d6d..ca61ba4 100644 --- a/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart
@@ -20,12 +20,18 @@ }); group('(AMD module system)', () { var setup = SetupCompilerOptions( - moduleFormat: ModuleFormat.amd, args: args, enableExperiments: []); + moduleFormat: ModuleFormat.amd, + args: args, + enableExperiments: [], + ); runSharedTests(setup, driver); }); group('(DDC module system)', () { final setup = SetupCompilerOptions( - moduleFormat: ModuleFormat.ddc, args: args, enableExperiments: []); + moduleFormat: ModuleFormat.ddc, + args: args, + enableExperiments: [], + ); runSharedTests(setup, driver); }); } @@ -158,35 +164,38 @@ '''; void runSharedTests( - SetupCompilerOptions setup, ExpressionEvaluationTestDriver driver) { - group('Runtime debugging API after loading sources but before running main |', - () { - var source = simpleClassSource; + SetupCompilerOptions setup, + ExpressionEvaluationTestDriver driver, +) { + group( + 'Runtime debugging API after loading sources but before running main |', + () { + var source = simpleClassSource; - // Set up and tear down after every test so that the bootstrapper script is - // re-run every time, therefore triggering the `OnScheduleMain` breakpoint. - setUp(() async { - await driver.initSource(setup, source); - }); + // Set up and tear down after every test so that the bootstrapper script is + // re-run every time, therefore triggering the `OnScheduleMain` breakpoint. + setUp(() async { + await driver.initSource(setup, source); + }); - tearDown(() async { - await driver.cleanupTest(); - }); + tearDown(() async { + await driver.cleanupTest(); + }); - test('getClassesInLibrary', () async { - var getClasses = setup.emitLibraryBundle - ? 'getClassesInLibrary' - : 'getLibraryMetadata'; - await driver.checkRuntimeInFrame( - breakpointId: 'OnScheduleMain', - // Query a user definition to test if it's initialized. - expression: 'dart.$getClasses("package:eval_test/test.dart")', - expectedResult: ['BaseClass', 'DerivedClass', 'AnotherClass'], - ); - }); + test('getClassesInLibrary', () async { + var getClasses = setup.emitLibraryBundle + ? 'getClassesInLibrary' + : 'getLibraryMetadata'; + await driver.checkRuntimeInFrame( + breakpointId: 'OnScheduleMain', + // Query a user definition to test if it's initialized. + expression: 'dart.$getClasses("package:eval_test/test.dart")', + expectedResult: ['BaseClass', 'DerivedClass', 'AnotherClass'], + ); + }); - test('getClassMetadata in non-SDK library', () async { - await driver.checkRuntimeInFrame( + test('getClassMetadata in non-SDK library', () async { + await driver.checkRuntimeInFrame( breakpointId: 'OnScheduleMain', // Query a user definition to test if it's initialized. expression: @@ -218,12 +227,14 @@ 'extensionTypeGetter': {'isGetter': true}, '_privateExtensionTypeGetter': {'isGetter': true}, }, - }); - }); - }, - // DDC module format doesn't guarantee that libraries are initialized when - // using debugging APIs before main is started. - skip: setup.moduleFormat == ModuleFormat.ddc && !setup.canaryFeatures); + }, + ); + }); + }, + // DDC module format doesn't guarantee that libraries are initialized when + // using debugging APIs before main is started. + skip: setup.moduleFormat == ModuleFormat.ddc && !setup.canaryFeatures, + ); group('Runtime debugging API |', () { var source = simpleClassSource; @@ -249,266 +260,278 @@ test('getClassMetadata (object)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getClassMetadata("dart:core", "Object")', - expectedResult: { - 'className': 'Object', - 'fields': {}, - 'methods': { - '_equals': {}, - 'toString': {}, - 'noSuchMethod': {}, - 'hashCode': {'isGetter': true}, - 'runtimeType': {'isGetter': true}, - 'hash': {'isStatic': true}, - 'hashAll': {'isStatic': true}, - 'hashAllUnordered': {'isStatic': true}, - } - }); + breakpointId: 'BP', + expression: 'dart.getClassMetadata("dart:core", "Object")', + expectedResult: { + 'className': 'Object', + 'fields': {}, + 'methods': { + '_equals': {}, + 'toString': {}, + 'noSuchMethod': {}, + 'hashCode': {'isGetter': true}, + 'runtimeType': {'isGetter': true}, + 'hash': {'isStatic': true}, + 'hashAll': {'isStatic': true}, + 'hashAllUnordered': {'isStatic': true}, + }, + }, + ); }); test('getClassMetadata (base class)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: - 'dart.getClassMetadata("package:eval_test/test.dart", "BaseClass", base)', - expectedResult: { - 'className': 'BaseClass', - 'superClassName': 'Object', - 'superClassLibraryId': 'dart:core', - 'fields': { - 'field': {'className': 'int', 'classLibraryId': 'dart:core'}, - 'functionField': {'className': '() => void'}, - 'nullableField': { - 'className': 'BaseClass<num>?', - 'classLibraryId': 'package:eval_test/test.dart', - }, - 'nonNullableField': { - 'className': 'AnotherClass', - 'classLibraryId': 'package:eval_test/test.dart', - }, - '_field': {'className': 'int', 'classLibraryId': 'dart:core'}, - 'genericField': {'className': 'int'}, - '_unusedField': { - 'className': 'int', - 'classLibraryId': 'dart:core', - }, - 'lateFinalField': { - 'className': 'int?', - 'classLibraryId': 'dart:core', - }, - 'staticConstField': {'isStatic': true}, - 'staticField': {'isStatic': true}, - '_staticField': {'isStatic': true}, - '_unusedStaticField': {'isStatic': true}, - // NOTE: Fields typed as an extension type appear as their static - // erased type for now. This isn't necessarily the runtime type - // of the value either. - 'extensionTypeField': { - 'className': 'String', - 'classLibraryId': 'dart:core', - }, - '_privateExtensionTypeField': { - 'className': 'String', - 'classLibraryId': 'dart:core', - }, - 'staticConstExtensionTypeField': {'isStatic': true}, - 'staticExtensionTypeField': {'isStatic': true}, - 'staticFinalExtensionTypeField': {'isStatic': true}, + breakpointId: 'BP', + expression: + 'dart.getClassMetadata("package:eval_test/test.dart", "BaseClass", base)', + expectedResult: { + 'className': 'BaseClass', + 'superClassName': 'Object', + 'superClassLibraryId': 'dart:core', + 'fields': { + 'field': {'className': 'int', 'classLibraryId': 'dart:core'}, + 'functionField': {'className': '() => void'}, + 'nullableField': { + 'className': 'BaseClass<num>?', + 'classLibraryId': 'package:eval_test/test.dart', }, - 'methods': { - 'method': {}, - '_privateMethod': {}, - 'lateFinalField': {'isGetter': true}, - 'getter': {'isGetter': true}, - '_privateGetter': {'isGetter': true}, - 'factory': {'isStatic': true}, - 'staticMethod': {'isStatic': true}, - 'extensionTypeGetter': {'isGetter': true}, - '_privateExtensionTypeGetter': {'isGetter': true}, + 'nonNullableField': { + 'className': 'AnotherClass', + 'classLibraryId': 'package:eval_test/test.dart', }, - }); + '_field': {'className': 'int', 'classLibraryId': 'dart:core'}, + 'genericField': {'className': 'int'}, + '_unusedField': {'className': 'int', 'classLibraryId': 'dart:core'}, + 'lateFinalField': { + 'className': 'int?', + 'classLibraryId': 'dart:core', + }, + 'staticConstField': {'isStatic': true}, + 'staticField': {'isStatic': true}, + '_staticField': {'isStatic': true}, + '_unusedStaticField': {'isStatic': true}, + // NOTE: Fields typed as an extension type appear as their static + // erased type for now. This isn't necessarily the runtime type + // of the value either. + 'extensionTypeField': { + 'className': 'String', + 'classLibraryId': 'dart:core', + }, + '_privateExtensionTypeField': { + 'className': 'String', + 'classLibraryId': 'dart:core', + }, + 'staticConstExtensionTypeField': {'isStatic': true}, + 'staticExtensionTypeField': {'isStatic': true}, + 'staticFinalExtensionTypeField': {'isStatic': true}, + }, + 'methods': { + 'method': {}, + '_privateMethod': {}, + 'lateFinalField': {'isGetter': true}, + 'getter': {'isGetter': true}, + '_privateGetter': {'isGetter': true}, + 'factory': {'isStatic': true}, + 'staticMethod': {'isStatic': true}, + 'extensionTypeGetter': {'isGetter': true}, + '_privateExtensionTypeGetter': {'isGetter': true}, + }, + }, + ); }); test('getClassMetadata (derived class)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: - 'dart.getClassMetadata("package:eval_test/test.dart", "DerivedClass")', - expectedResult: { - 'className': 'DerivedClass', - 'superClassName': 'BaseClass', - 'superClassLibraryId': 'package:eval_test/test.dart', - 'fields': { - 'newPublicField': { - 'isFinal': true, - 'className': 'int', - 'classLibraryId': 'dart:core', - }, - '_newPrivateField': { - 'isFinal': true, - 'className': 'int', - 'classLibraryId': 'dart:core', - }, - '_newStaticConstPrivateField': {'isStatic': true}, + breakpointId: 'BP', + expression: + 'dart.getClassMetadata("package:eval_test/test.dart", "DerivedClass")', + expectedResult: { + 'className': 'DerivedClass', + 'superClassName': 'BaseClass', + 'superClassLibraryId': 'package:eval_test/test.dart', + 'fields': { + 'newPublicField': { + 'isFinal': true, + 'className': 'int', + 'classLibraryId': 'dart:core', }, - 'methods': { - 'stringLength': {}, - 'lateFinalField': {'isGetter': true}, - 'getter': {'isGetter': true}, - '_privateGetter': {'isGetter': true}, - 'factory': {'isStatic': true}, - 'staticMethod': {'isStatic': true}, - 'extensionTypeGetter': {'isGetter': true}, - '_privateExtensionTypeGetter': {'isGetter': true}, + '_newPrivateField': { + 'isFinal': true, + 'className': 'int', + 'classLibraryId': 'dart:core', }, - }); + '_newStaticConstPrivateField': {'isStatic': true}, + }, + 'methods': { + 'stringLength': {}, + 'lateFinalField': {'isGetter': true}, + 'getter': {'isGetter': true}, + '_privateGetter': {'isGetter': true}, + 'factory': {'isStatic': true}, + 'staticMethod': {'isStatic': true}, + 'extensionTypeGetter': {'isGetter': true}, + '_privateExtensionTypeGetter': {'isGetter': true}, + }, + }, + ); }); test('getClassMetadata (Record)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getClassMetadata("dart:core", "Record")', - expectedResult: { - 'className': 'Record', - 'superClassName': 'Object', - 'superClassLibraryId': 'dart:core', - 'fields': {}, - 'methods': { - '_equals': {}, - 'toString': {}, - 'noSuchMethod': {}, - 'hashCode': {'isGetter': true}, - 'runtimeType': {'isGetter': true}, - 'hash': {'isStatic': true}, - 'hashAll': {'isStatic': true}, - 'hashAllUnordered': {'isStatic': true}, - } - }); + breakpointId: 'BP', + expression: 'dart.getClassMetadata("dart:core", "Record")', + expectedResult: { + 'className': 'Record', + 'superClassName': 'Object', + 'superClassLibraryId': 'dart:core', + 'fields': {}, + 'methods': { + '_equals': {}, + 'toString': {}, + 'noSuchMethod': {}, + 'hashCode': {'isGetter': true}, + 'runtimeType': {'isGetter': true}, + 'hash': {'isStatic': true}, + 'hashAll': {'isStatic': true}, + 'hashAllUnordered': {'isStatic': true}, + }, + }, + ); }); test('getObjectMetadata (int)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(x)', - expectedResult: {}); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(x)', + expectedResult: {}, + ); }); test('getObjectMetadata (object)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(object)', - expectedResult: { - 'className': 'Object', - 'libraryId': 'dart:core', - 'runtimeKind': 'object', - 'length': 0, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(object)', + expectedResult: { + 'className': 'Object', + 'libraryId': 'dart:core', + 'runtimeKind': 'object', + 'length': 0, + }, + ); }); test('getObjectMetadata (object of derived class)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(base)', - expectedResult: { - 'className': 'BaseClass<int>', - 'libraryId': 'package:eval_test/test.dart', - 'runtimeKind': 'object', - 'length': 10, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(base)', + expectedResult: { + 'className': 'BaseClass<int>', + 'libraryId': 'package:eval_test/test.dart', + 'runtimeKind': 'object', + 'length': 10, + }, + ); }); test('getObjectMetadata (Set)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(set)', - expectedResult: { - 'className': 'LinkedSet<String>', - 'libraryId': 'dart:_js_helper', - 'runtimeKind': 'set', - 'length': 3, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(set)', + expectedResult: { + 'className': 'LinkedSet<String>', + 'libraryId': 'dart:_js_helper', + 'runtimeKind': 'set', + 'length': 3, + }, + ); }); test('getObjectMetadata (List)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(list)', - expectedResult: { - 'className': 'JSArray<int>', - 'libraryId': 'dart:_interceptors', - 'runtimeKind': 'list', - 'length': 3, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(list)', + expectedResult: { + 'className': 'JSArray<int>', + 'libraryId': 'dart:_interceptors', + 'runtimeKind': 'list', + 'length': 3, + }, + ); }); test('getObjectMetadata (Map)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(map)', - expectedResult: { - 'className': 'IdentityMap<String, int>', - 'libraryId': 'dart:_js_helper', - 'runtimeKind': 'map', - 'length': 2, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(map)', + expectedResult: { + 'className': 'IdentityMap<String, int>', + 'libraryId': 'dart:_js_helper', + 'runtimeKind': 'map', + 'length': 2, + }, + ); }); test('getObjectMetadata (Stream)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(stream)', - expectedResult: { - 'className': '_MultiStream<int>', - 'libraryId': 'dart:async', - 'runtimeKind': 'object', - 'length': 2, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(stream)', + expectedResult: { + 'className': '_MultiStream<int>', + 'libraryId': 'dart:async', + 'runtimeKind': 'object', + 'length': 2, + }, + ); }); test('getObjectMetadata (Record)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(record)', - expectedResult: { - 'className': 'Record', - 'libraryId': 'dart:core', - 'runtimeKind': 'record', - 'length': 3, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(record)', + expectedResult: { + 'className': 'Record', + 'libraryId': 'dart:core', + 'runtimeKind': 'record', + 'length': 3, + }, + ); }); test('getObjectMetadata (LegacyJavaScriptObject)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata({})', - expectedResult: { - 'className': 'LegacyJavaScriptObject', - 'libraryId': 'dart:_interceptors', - 'runtimeKind': 'nativeObject', - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata({})', + expectedResult: { + 'className': 'LegacyJavaScriptObject', + 'libraryId': 'dart:_interceptors', + 'runtimeKind': 'nativeObject', + }, + ); }); test('getObjectMetadata (NativeError)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(new Error())', - expectedResult: { - 'className': 'NativeError', - 'libraryId': 'dart:_interceptors', - 'runtimeKind': 'nativeError', - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(new Error())', + expectedResult: { + 'className': 'NativeError', + 'libraryId': 'dart:_interceptors', + 'runtimeKind': 'nativeError', + }, + ); }); test('getObjectMetadata (DartError)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(error)', - expectedResult: { - 'className': 'NativeError', - 'libraryId': 'dart:_interceptors', - 'runtimeKind': 'nativeError', - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(error)', + expectedResult: { + 'className': 'NativeError', + 'libraryId': 'dart:_interceptors', + 'runtimeKind': 'nativeError', + }, + ); }); test('typeName (int type)', () async { @@ -533,14 +556,15 @@ expression: 'xType.toString()', ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(xType)', - expectedResult: { - 'className': 'Type', - 'libraryId': 'dart:core', - 'runtimeKind': 'type', - 'typeName': typeName, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(xType)', + expectedResult: { + 'className': 'Type', + 'libraryId': 'dart:core', + 'runtimeKind': 'type', + 'typeName': typeName, + }, + ); }); test('getObjectMetadata (base type)', () async { @@ -549,14 +573,15 @@ expression: 'baseType.toString()', ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(baseType)', - expectedResult: { - 'className': 'Type', - 'libraryId': 'dart:core', - 'runtimeKind': 'type', - 'typeName': typeName, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(baseType)', + expectedResult: { + 'className': 'Type', + 'libraryId': 'dart:core', + 'runtimeKind': 'type', + 'typeName': typeName, + }, + ); }); test('getObjectMetadata (type)', () async { @@ -565,14 +590,15 @@ expression: 'baseTypeType.toString()', ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(baseTypeType)', - expectedResult: { - 'className': 'Type', - 'libraryId': 'dart:core', - 'runtimeKind': 'type', - 'typeName': typeName, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(baseTypeType)', + expectedResult: { + 'className': 'Type', + 'libraryId': 'dart:core', + 'runtimeKind': 'type', + 'typeName': typeName, + }, + ); }); test('getObjectMetadata (Set type)', () async { @@ -581,14 +607,15 @@ expression: 'setType.toString()', ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(setType)', - expectedResult: { - 'className': 'Type', - 'libraryId': 'dart:core', - 'runtimeKind': 'type', - 'typeName': typeName, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(setType)', + expectedResult: { + 'className': 'Type', + 'libraryId': 'dart:core', + 'runtimeKind': 'type', + 'typeName': typeName, + }, + ); }); test('getObjectMetadata (List type)', () async { @@ -597,14 +624,15 @@ expression: 'listType.toString()', ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(listType)', - expectedResult: { - 'className': 'Type', - 'libraryId': 'dart:core', - 'runtimeKind': 'type', - 'typeName': typeName, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(listType)', + expectedResult: { + 'className': 'Type', + 'libraryId': 'dart:core', + 'runtimeKind': 'type', + 'typeName': typeName, + }, + ); }); test('getObjectMetadata (Map type)', () async { @@ -613,14 +641,15 @@ expression: 'mapType.toString()', ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(mapType)', - expectedResult: { - 'className': 'Type', - 'libraryId': 'dart:core', - 'runtimeKind': 'type', - 'typeName': typeName, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(mapType)', + expectedResult: { + 'className': 'Type', + 'libraryId': 'dart:core', + 'runtimeKind': 'type', + 'typeName': typeName, + }, + ); }); test('getObjectMetadata (Record type)', () async { @@ -631,14 +660,15 @@ expect(typeName, '(int, int, {String name})'); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectMetadata(recordType)', - expectedResult: { - 'className': 'Type', - 'libraryId': 'dart:core', - 'runtimeKind': 'recordType', - 'length': 3, - }); + breakpointId: 'BP', + expression: 'dart.getObjectMetadata(recordType)', + expectedResult: { + 'className': 'Type', + 'libraryId': 'dart:core', + 'runtimeKind': 'recordType', + 'length': 3, + }, + ); await driver.checkInFrame( breakpointId: 'BP', @@ -655,175 +685,203 @@ test('getObjectFieldNames (object)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectFieldNames(object)', - expectedResult: []); + breakpointId: 'BP', + expression: 'dart.getObjectFieldNames(object)', + expectedResult: [], + ); }); test('getObjectFieldNames (derived class)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectFieldNames(derived)', - expectedResult: [ - '_field', - '_newPrivateField', - '_privateExtensionTypeField', - '_unusedField', - 'extensionTypeField', - 'field', - 'functionField', - 'genericField', - 'lateFinalField', - 'newPublicField', - 'nonNullableField', - 'nullableField', - ]); + breakpointId: 'BP', + expression: 'dart.getObjectFieldNames(derived)', + expectedResult: [ + '_field', + '_newPrivateField', + '_privateExtensionTypeField', + '_unusedField', + 'extensionTypeField', + 'field', + 'functionField', + 'genericField', + 'lateFinalField', + 'newPublicField', + 'nonNullableField', + 'nullableField', + ], + ); }); test('getObjectFieldNames (base class)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getObjectFieldNames(base)', - expectedResult: [ - '_field', - '_privateExtensionTypeField', - '_unusedField', - 'extensionTypeField', - 'field', - 'functionField', - 'genericField', - 'lateFinalField', - 'nonNullableField', - 'nullableField', - ]); + breakpointId: 'BP', + expression: 'dart.getObjectFieldNames(base)', + expectedResult: [ + '_field', + '_privateExtensionTypeField', + '_unusedField', + 'extensionTypeField', + 'field', + 'functionField', + 'genericField', + 'lateFinalField', + 'nonNullableField', + 'nullableField', + ], + ); }); test('getSetElements', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getSetElements(set)', - expectedResult: { - 'entries': ['a', 'b', 'c'], - }); + breakpointId: 'BP', + expression: 'dart.getSetElements(set)', + expectedResult: { + 'entries': ['a', 'b', 'c'], + }, + ); }); test('getMapElements', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getMapElements(map)', - expectedResult: { - 'keys': ['a', 'b'], - 'values': [1, 2], - }); + breakpointId: 'BP', + expression: 'dart.getMapElements(map)', + expectedResult: { + 'keys': ['a', 'b'], + 'values': [1, 2], + }, + ); }); test('getRecordFields', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getRecordFields(record)', - expectedResult: { - 'positionalCount': 2, - 'named': ['name'], - 'values': [0, 2, 'cat'], - }); + breakpointId: 'BP', + expression: 'dart.getRecordFields(record)', + expectedResult: { + 'positionalCount': 2, + 'named': ['name'], + 'values': [0, 2, 'cat'], + }, + ); }); // TODO(annagrin): Add recursive check for nested objects. test('getRecordTypeFields', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getRecordTypeFields(recordType)', - expectedResult: { - 'positionalCount': 2, - 'named': ['name'], - 'types': [{}, {}, {}], - }); + breakpointId: 'BP', + expression: 'dart.getRecordTypeFields(recordType)', + expectedResult: { + 'positionalCount': 2, + 'named': ['name'], + 'types': [{}, {}, {}], + }, + ); }); test('getFunctionName (method)', () async { - var getFunctionName = - setup.emitLibraryBundle ? 'getFunctionName' : 'getFunctionMetadata'; + var getFunctionName = setup.emitLibraryBundle + ? 'getFunctionName' + : 'getFunctionMetadata'; await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.$getFunctionName(base.method)', - expectedResult: 'method'); + breakpointId: 'BP', + expression: 'dart.$getFunctionName(base.method)', + expectedResult: 'method', + ); }); test('getFunctionName (static method)', () async { - var getFunctionName = - setup.emitLibraryBundle ? 'getFunctionName' : 'getFunctionMetadata'; + var getFunctionName = setup.emitLibraryBundle + ? 'getFunctionName' + : 'getFunctionMetadata'; var expectedName = 'BaseClass.staticMethod'; await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.$getFunctionName(staticMethod)', - expectedResult: expectedName); + breakpointId: 'BP', + expression: 'dart.$getFunctionName(staticMethod)', + expectedResult: expectedName, + ); }); test('getFunctionName (global method)', () async { - var getFunctionName = - setup.emitLibraryBundle ? 'getFunctionName' : 'getFunctionMetadata'; + var getFunctionName = setup.emitLibraryBundle + ? 'getFunctionName' + : 'getFunctionMetadata'; await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.$getFunctionName(globalMethod)', - expectedResult: 'globalFunction'); + breakpointId: 'BP', + expression: 'dart.$getFunctionName(globalMethod)', + expectedResult: 'globalFunction', + ); }); test('getSubRange (set)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getSubRange(set, 0, 3)', - expectedResult: ['a', 'b', 'c']); + breakpointId: 'BP', + expression: 'dart.getSubRange(set, 0, 3)', + expectedResult: ['a', 'b', 'c'], + ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getSubRange(set, 1, 2)', - expectedResult: ['b', 'c']); + breakpointId: 'BP', + expression: 'dart.getSubRange(set, 1, 2)', + expectedResult: ['b', 'c'], + ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getSubRange(set, 1, 5)', - expectedResult: ['b', 'c']); + breakpointId: 'BP', + expression: 'dart.getSubRange(set, 1, 5)', + expectedResult: ['b', 'c'], + ); }); test('getSubRange (list)', () async { await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getSubRange(list, 0, 3)', - expectedResult: [1, 2, 3]); + breakpointId: 'BP', + expression: 'dart.getSubRange(list, 0, 3)', + expectedResult: [1, 2, 3], + ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getSubRange(list, 1, 2)', - expectedResult: [2, 3]); + breakpointId: 'BP', + expression: 'dart.getSubRange(list, 1, 2)', + expectedResult: [2, 3], + ); await driver.checkRuntimeInFrame( - breakpointId: 'BP', - expression: 'dart.getSubRange(list, 1, 5)', - expectedResult: [2, 3]); + breakpointId: 'BP', + expression: 'dart.getSubRange(list, 1, 5)', + expectedResult: [2, 3], + ); }); test('getSubRange (map)', () async { await driver.checkRuntimeInFrame( breakpointId: 'BP', expression: 'dart.getSubRange(map, 0, 3)', - expectedResult: - isA<List>().having((p) => p.length, 'length', equals(2)), + expectedResult: isA<List>().having( + (p) => p.length, + 'length', + equals(2), + ), ); await driver.checkRuntimeInFrame( breakpointId: 'BP', expression: 'dart.getSubRange(map, 1, 2)', - expectedResult: - isA<List>().having((p) => p.length, 'length', equals(1)), + expectedResult: isA<List>().having( + (p) => p.length, + 'length', + equals(1), + ), ); await driver.checkRuntimeInFrame( breakpointId: 'BP', expression: 'dart.getSubRange(map, 1, 5)', - expectedResult: - isA<List>().having((p) => p.length, 'length', equals(1)), + expectedResult: isA<List>().having( + (p) => p.length, + 'length', + equals(1), + ), ); }); @@ -836,7 +894,7 @@ 'className': 'DerivedClass', 'libraryId': 'package:eval_test/test.dart', 'runtimeKind': 'object', - 'length': 12 + 'length': 12, }, ); }, skip: !setup.emitLibraryBundle); @@ -1057,7 +1115,7 @@ }); group('part files expression compilations |', () { - // WARNING: The (main) source and the part source have been constructred + // WARNING: The (main) source and the part source have been constructed // so that the same offset (71) is valid on both, and both have an 'x' // variable, where one is a String and the other is an int. The 4 dots after // 'padding' for instance is not a mistake.
diff --git a/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart b/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart index e661c06..2903d80 100644 --- a/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/scope_offset_test.dart
@@ -12,8 +12,9 @@ /// Verbose mode for debugging bool get verbose => false; -Uri sdkSummaryPath = - computePlatformBinariesLocation().resolve('ddc_outline.dill'); +Uri sdkSummaryPath = computePlatformBinariesLocation().resolve( + 'ddc_outline.dill', +); void main(List<String> args) { test('Offsets are present on scoping nodes in SDK', () async { @@ -21,8 +22,10 @@ var bytes = await entity.readAsBytes(); var component = Component(); - BinaryBuilderWithMetadata(bytes, disableLazyReading: true) - .readComponent(component, checkCanonicalNames: true, createView: true); + BinaryBuilderWithMetadata( + bytes, + disableLazyReading: true, + ).readComponent(component, checkCanonicalNames: true, createView: true); for (var lib in component.libraries) { ScopeOffsetValidator.validate(lib); @@ -44,11 +47,17 @@ // TODO(joshualitt): Currently, there's nothing in `dart:_js_types` that // would be indexed. Remove this exception when we add things to it. if (importUri != 'dart:_js_types' && importUri != 'dart:_ddc_only') { - expect(validator.classCount + validator.memberCount, greaterThan(0), - reason: 'Validation was not empty'); + expect( + validator.classCount + validator.memberCount, + greaterThan(0), + reason: 'Validation was not empty', + ); } - expect(validator.blockCount, equals(0), - reason: 'SDK dill only contains outlines'); + expect( + validator.blockCount, + equals(0), + reason: 'SDK dill only contains outlines', + ); } @override @@ -60,12 +69,19 @@ void visitClass(Class cls) { classCount++; expect( - cls, - const TypeMatcher<Class>() - .having((c) => c.fileOffset, '${cls.name} : fileOffset', - isNot(equals(-1))) - .having((c) => c.fileEndOffset, '${cls.name} : fileEndOffset', - isNot(equals(-1)))); + cls, + const TypeMatcher<Class>() + .having( + (c) => c.fileOffset, + '${cls.name} : fileOffset', + isNot(equals(-1)), + ) + .having( + (c) => c.fileEndOffset, + '${cls.name} : fileEndOffset', + isNot(equals(-1)), + ), + ); super.visitClass(cls); } @@ -77,25 +93,28 @@ var noBreakPointPossible = (member is Constructor) ? member.isSynthetic : (member is Procedure) - ? member.isNoSuchMethodForwarder || - member.isAbstract || - member.isForwardingStub || - member.stubKind == ProcedureStubKind.ConcreteMixinStub - : false; + ? member.isNoSuchMethodForwarder || + member.isAbstract || + member.isForwardingStub || + member.stubKind == ProcedureStubKind.ConcreteMixinStub + : false; if (!noBreakPointPossible) { memberCount++; expect( - member, - const TypeMatcher<Member>() - .having( - (c) => c.fileOffset, - '${member.enclosingClass}.${member.name} : fileOffset', - isNot(equals(-1))) - .having( - (c) => c.fileEndOffset, - '${member.enclosingClass}.${member.name} : fileEndOffset', - isNot(equals(-1)))); + member, + const TypeMatcher<Member>() + .having( + (c) => c.fileOffset, + '${member.enclosingClass}.${member.name} : fileOffset', + isNot(equals(-1)), + ) + .having( + (c) => c.fileEndOffset, + '${member.enclosingClass}.${member.name} : fileEndOffset', + isNot(equals(-1)), + ), + ); super.defaultMember(member); } @@ -104,16 +123,19 @@ @override void visitFunctionNode(FunctionNode fun) { expect( - fun, - const TypeMatcher<FunctionNode>() - .having( - (c) => c.fileOffset, - '${fun.parent!.toText(astTextStrategyForTesting)} : fileOffset', - isNot(equals(-1))) - .having( - (c) => c.fileEndOffset, - '${fun.parent!.toText(astTextStrategyForTesting)} : fileEndOffset', - isNot(equals(-1)))); + fun, + const TypeMatcher<FunctionNode>() + .having( + (c) => c.fileOffset, + '${fun.parent!.toText(astTextStrategyForTesting)} : fileOffset', + isNot(equals(-1)), + ) + .having( + (c) => c.fileEndOffset, + '${fun.parent!.toText(astTextStrategyForTesting)} : fileEndOffset', + isNot(equals(-1)), + ), + ); super.visitFunctionNode(fun); } @@ -122,15 +144,20 @@ void visitBlock(Block block) { blockCount++; expect( - block, - const TypeMatcher<FunctionNode>().having( - (c) => c.fileOffset, - '${block.toText(astTextStrategyForTesting)} : fileOffset', - isNot(equals(-1)))); + block, + const TypeMatcher<FunctionNode>().having( + (c) => c.fileOffset, + '${block.toText(astTextStrategyForTesting)} : fileOffset', + isNot(equals(-1)), + ), + ); var fileEndOffset = FileEndOffsetCalculator.calculateEndOffset(block); - expect(fileEndOffset, isNot(equals(-1)), - reason: '${block.toText(astTextStrategyForTesting)} : fileOffset'); + expect( + fileEndOffset, + isNot(equals(-1)), + reason: '${block.toText(astTextStrategyForTesting)} : fileOffset', + ); super.visitBlock(block); }
diff --git a/pkg/dev_compiler/test/expression_compiler/test_compiler.dart b/pkg/dev_compiler/test/expression_compiler/test_compiler.dart index 209330e..a45441b 100644 --- a/pkg/dev_compiler/test/expression_compiler/test_compiler.dart +++ b/pkg/dev_compiler/test/expression_compiler/test_compiler.dart
@@ -37,22 +37,32 @@ final source_maps.SingleMapping sourceMap; TestExpressionCompiler._( - this.setup, this.component, this.compiler, this.metadata, this.sourceMap); + this.setup, + this.component, + this.compiler, + this.metadata, + this.sourceMap, + ); - static Future<TestExpressionCompiler> init(SetupCompilerOptions setup, - {required Uri input, - required Uri output, - Uri? packages, - Map<String, bool> experiments = const {}}) async { + static Future<TestExpressionCompiler> init( + SetupCompilerOptions setup, { + required Uri input, + required Uri output, + Uri? packages, + Map<String, bool> experiments = const {}, + }) async { setup.diagnosticMessages.clear(); setup.errors.clear(); // Initialize the incremental compiler and module component. // TODO: extend this for multi-module compilations by storing separate // compilers/components/names per module. setup.options.packagesFileUri = packages; - setup.options.explicitExperimentalFlags.addAll(fe.parseExperimentalFlags( + setup.options.explicitExperimentalFlags.addAll( + fe.parseExperimentalFlags( experiments, - onError: (message) => throw Exception(message))); + onError: (message) => throw Exception(message), + ), + ); var frontend = DevelopmentIncrementalCompiler(setup.options, input); var compilerResult = await frontend.computeDelta(); var component = compilerResult.component; @@ -80,11 +90,22 @@ summaryToModule[component] = moduleName; var kernel2jsCompiler = compilerOptions.emitLibraryBundle - ? LibraryBundleCompiler(component, classHierarchy, compilerOptions, - importToSummary, summaryToModule, coreTypes: coreTypes) - : ProgramCompiler(component, classHierarchy, compilerOptions, - importToSummary, summaryToModule, - coreTypes: coreTypes); + ? LibraryBundleCompiler( + component, + classHierarchy, + compilerOptions, + importToSummary, + summaryToModule, + coreTypes: coreTypes, + ) + : ProgramCompiler( + component, + classHierarchy, + compilerOptions, + importToSummary, + summaryToModule, + coreTypes: coreTypes, + ); var module = kernel2jsCompiler.emitModule(component); var moduleFormat = compilerOptions.emitLibraryBundle @@ -128,17 +149,23 @@ var sourceMap = source_maps.SingleMapping.fromJson(code.sourceMap!); return TestExpressionCompiler._( - setup, component, compiler, code.metadata, sourceMap); + setup, + component, + compiler, + code.metadata, + sourceMap, + ); } // Line and column are 1-based. - Future<TestCompilationResult> compileExpression( - {required Uri libraryUri, - Uri? scriptUri, - required int line, - required int column, - required Map<String, String> scope, - required String expression}) async { + Future<TestCompilationResult> compileExpression({ + required Uri libraryUri, + Uri? scriptUri, + required int line, + required int column, + required Map<String, String> scope, + required String expression, + }) async { // clear previous errors setup.errors.clear(); @@ -154,12 +181,18 @@ importUri = libraryMetadata.importUri; } var jsExpression = await compiler.compileExpressionToJs( - importUri, scriptUri?.toString(), line, column, scope, expression); + importUri, + scriptUri?.toString(), + line, + column, + scope, + expression, + ); if (setup.errors.isNotEmpty) { jsExpression = setup.errors.toString().replaceAll( - RegExp( - r'org-dartlang-debug:synthetic_debug_expression:[0-9]*:[0-9]*:'), - ''); + RegExp(r'org-dartlang-debug:synthetic_debug_expression:[0-9]*:[0-9]*:'), + '', + ); return TestCompilationResult(jsExpression, false); } @@ -167,8 +200,9 @@ return TestCompilationResult(jsExpression, true); } - LibraryMetadata metadataForLibraryUri(Uri libraryUri) => - metadata!.libraries.entries - .firstWhere((entry) => entry.value.fileUri == '$libraryUri') - .value; + LibraryMetadata metadataForLibraryUri(Uri libraryUri) => metadata! + .libraries + .entries + .firstWhere((entry) => entry.value.fileUri == '$libraryUri') + .value; }
diff --git a/pkg/dev_compiler/test/hot_reload_delta_flags_test.dart b/pkg/dev_compiler/test/hot_reload_delta_flags_test.dart index 4fbf0f4..cadf2f3 100644 --- a/pkg/dev_compiler/test/hot_reload_delta_flags_test.dart +++ b/pkg/dev_compiler/test/hot_reload_delta_flags_test.dart
@@ -37,9 +37,9 @@ '''; String _resolvePath(String executableRelativePath) { - return Uri.file(Platform.resolvedExecutable) - .resolve(executableRelativePath) - .toFilePath(); + return Uri.file( + Platform.resolvedExecutable, + ).resolve(executableRelativePath).toFilePath(); } Future<void> main() async { @@ -61,11 +61,16 @@ tmp.deleteSync(recursive: true); }); - void runDDC(List<String> flags, String programSource, - {String? expectError}) async { + void runDDC( + List<String> flags, + String programSource, { + String? expectError, + }) async { final sdkPath = p.dirname(Platform.executable); - final dartAotRuntime = p.absolute(sdkPath, - Platform.isWindows ? 'dartaotruntime.exe' : 'dartaotruntime'); + final dartAotRuntime = p.absolute( + sdkPath, + Platform.isWindows ? 'dartaotruntime.exe' : 'dartaotruntime', + ); final snapshotName = _resolvePath('snapshots/dartdevc_aot.dart.snapshot'); final outlinePath = _resolvePath('../lib/_internal/ddc_outline.dill'); @@ -109,34 +114,42 @@ expect(outputJs.statSync().size, isNonNegative); }); - test('providing delta output and last accepted input flag valid change', - () { - runDDC(['--reload-delta-kernel=${lastAcceptedDill.path}'], program1); - expect(lastAcceptedDill.existsSync(), isTrue); - expect(lastAcceptedDill.statSync().size, isNonNegative); + test( + 'providing delta output and last accepted input flag valid change', + () { + runDDC(['--reload-delta-kernel=${lastAcceptedDill.path}'], program1); + expect(lastAcceptedDill.existsSync(), isTrue); + expect(lastAcceptedDill.statSync().size, isNonNegative); - runDDC([ - '--reload-last-accepted-kernel=${lastAcceptedDill.path}', - '--reload-delta-kernel=${deltaDill.path}' - ], program2Valid); - expect(lastAcceptedDill.existsSync(), isTrue); - expect(lastAcceptedDill.statSync().size, isNonNegative); - expect(deltaDill.existsSync(), isTrue); - expect(deltaDill.statSync().size, isNonNegative); - expect(outputJs.existsSync(), isTrue); - expect(outputJs.statSync().size, isNonNegative); - }); + runDDC([ + '--reload-last-accepted-kernel=${lastAcceptedDill.path}', + '--reload-delta-kernel=${deltaDill.path}', + ], program2Valid); + expect(lastAcceptedDill.existsSync(), isTrue); + expect(lastAcceptedDill.statSync().size, isNonNegative); + expect(deltaDill.existsSync(), isTrue); + expect(deltaDill.statSync().size, isNonNegative); + expect(outputJs.existsSync(), isTrue); + expect(outputJs.statSync().size, isNonNegative); + }, + ); - test('providing delta output and last accepted input flag invalid change', - () { - runDDC(['--reload-delta-kernel=${lastAcceptedDill.path}'], program1); - runDDC([ - '--reload-last-accepted-kernel=${lastAcceptedDill.path}', - '--reload-delta-kernel=${deltaDill.path}' - ], program2Error, expectError: 'Const class cannot remove fields'); - expect(lastAcceptedDill.existsSync(), isTrue); - expect(lastAcceptedDill.statSync().size, isNonNegative); - expect(deltaDill.existsSync(), isFalse); - }); + test( + 'providing delta output and last accepted input flag invalid change', + () { + runDDC(['--reload-delta-kernel=${lastAcceptedDill.path}'], program1); + runDDC( + [ + '--reload-last-accepted-kernel=${lastAcceptedDill.path}', + '--reload-delta-kernel=${deltaDill.path}', + ], + program2Error, + expectError: 'Const class cannot remove fields', + ); + expect(lastAcceptedDill.existsSync(), isTrue); + expect(lastAcceptedDill.statSync().size, isNonNegative); + expect(deltaDill.existsSync(), isFalse); + }, + ); }); }
diff --git a/pkg/dev_compiler/test/hot_reload_delta_inspector_test.dart b/pkg/dev_compiler/test/hot_reload_delta_inspector_test.dart index 55c7f31..67109f8 100644 --- a/pkg/dev_compiler/test/hot_reload_delta_inspector_test.dart +++ b/pkg/dev_compiler/test/hot_reload_delta_inspector_test.dart
@@ -38,15 +38,18 @@ print('hello world'); } '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); expect( - deltaInspector.compareGenerations(initial, delta), - unorderedEquals([ - 'Const class cannot become non-const: ' - "Library:'memory:///main.dart' " - 'Class: A' - ])); + deltaInspector.compareGenerations(initial, delta), + unorderedEquals([ + 'Const class cannot become non-const: ' + "Library:'memory:///main.dart' " + 'Class: A', + ]), + ); }); test('multiple rejections when removing only const constructors', () async { final initialSource = ''' @@ -110,23 +113,27 @@ print('hello world'); } '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); expect( - deltaInspector.compareGenerations(initial, delta), - unorderedEquals([ - 'Const class cannot become non-const: ' - "Library:'memory:///main.dart' " - 'Class: A', - 'Const class cannot become non-const: ' - "Library:'memory:///main.dart' " - 'Class: D' - ])); + deltaInspector.compareGenerations(initial, delta), + unorderedEquals([ + 'Const class cannot become non-const: ' + "Library:'memory:///main.dart' " + 'Class: A', + 'Const class cannot become non-const: ' + "Library:'memory:///main.dart' " + 'Class: D', + ]), + ); }); - test('no error when removing const constructor while adding another', - () async { - final initialSource = ''' + test( + 'no error when removing const constructor while adding another', + () async { + final initialSource = ''' var globalVariable; class A { @@ -139,7 +146,7 @@ print(globalVariable.s); } '''; - final deltaSource = ''' + final deltaSource = ''' var globalVariable; class A { @@ -152,10 +159,13 @@ print('hello world'); } '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); - expect(deltaInspector.compareGenerations(initial, delta), isEmpty); - }); + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); + expect(deltaInspector.compareGenerations(initial, delta), isEmpty); + }, + ); test('rejection when removing a field', () async { final initialSource = ''' var globalVariable; @@ -182,14 +192,17 @@ print('hello world'); } '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); expect( - deltaInspector.compareGenerations(initial, delta), - unorderedEquals([ - 'Const class cannot remove fields: ' - "Library:'memory:///main.dart' Class: A" - ])); + deltaInspector.compareGenerations(initial, delta), + unorderedEquals([ + 'Const class cannot remove fields: ' + "Library:'memory:///main.dart' Class: A", + ]), + ); }); test('rejection when removing a field while adding another', () async { final initialSource = ''' @@ -217,18 +230,22 @@ print('hello world'); } '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); expect( - deltaInspector.compareGenerations(initial, delta), - unorderedEquals([ - 'Const class cannot remove fields: ' - "Library:'memory:///main.dart' Class: A" - ])); + deltaInspector.compareGenerations(initial, delta), + unorderedEquals([ + 'Const class cannot remove fields: ' + "Library:'memory:///main.dart' Class: A", + ]), + ); }); - test('no error when removing field while also making class const', - () async { - final initialSource = ''' + test( + 'no error when removing field while also making class const', + () async { + final initialSource = ''' var globalVariable; class A { @@ -241,7 +258,7 @@ print(globalVariable.s); } '''; - final deltaSource = ''' + final deltaSource = ''' var globalVariable; class A { @@ -253,11 +270,16 @@ print('hello world'); } '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); - expect(() => deltaInspector.compareGenerations(initial, delta), - returnsNormally); - }); + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); + expect( + () => deltaInspector.compareGenerations(initial, delta), + returnsNormally, + ); + }, + ); }); group('deleted top level members appear in delta library metadata', () { final deltaInspector = HotReloadDeltaInspector(); @@ -278,15 +300,22 @@ set retainedSetter(dynamic value) {} '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); - expect(() => deltaInspector.compareGenerations(initial, delta), - returnsNormally); - final repo = delta.metadata[hotReloadLibraryMetadataTag] - as HotReloadLibraryMetadataRepository; + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); + expect( + () => deltaInspector.compareGenerations(initial, delta), + returnsNormally, + ); + final repo = + delta.metadata[hotReloadLibraryMetadataTag] + as HotReloadLibraryMetadataRepository; repo.mapToIndexedNodes(LibraryIndex.all(delta)); - final metadata = repo.mapping[delta.libraries - .firstWhere((l) => l.importUri.toString() == 'memory:///main.dart')]!; + final metadata = + repo.mapping[delta.libraries.firstWhere( + (l) => l.importUri.toString() == 'memory:///main.dart', + )]!; expect(metadata.deletedStaticProcedureNames, orderedEquals(['deleted'])); }); test('getter', () async { @@ -306,17 +335,26 @@ set retainedSetter(dynamic value) {} '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); - expect(() => deltaInspector.compareGenerations(initial, delta), - returnsNormally); - final repo = delta.metadata[hotReloadLibraryMetadataTag] - as HotReloadLibraryMetadataRepository; + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); + expect( + () => deltaInspector.compareGenerations(initial, delta), + returnsNormally, + ); + final repo = + delta.metadata[hotReloadLibraryMetadataTag] + as HotReloadLibraryMetadataRepository; repo.mapToIndexedNodes(LibraryIndex.all(delta)); - final metadata = repo.mapping[delta.libraries - .firstWhere((l) => l.importUri.toString() == 'memory:///main.dart')]!; - expect(metadata.deletedStaticProcedureNames, - orderedEquals(['deletedGetter'])); + final metadata = + repo.mapping[delta.libraries.firstWhere( + (l) => l.importUri.toString() == 'memory:///main.dart', + )]!; + expect( + metadata.deletedStaticProcedureNames, + orderedEquals(['deletedGetter']), + ); }); test('setter', () async { final initialSource = ''' @@ -335,27 +373,38 @@ set retainedSetter(dynamic value) {} '''; - final (:initial, :delta) = - await compileComponents(initialSource, deltaSource); - expect(() => deltaInspector.compareGenerations(initial, delta), - returnsNormally); - final repo = delta.metadata[hotReloadLibraryMetadataTag] - as HotReloadLibraryMetadataRepository; + final (:initial, :delta) = await compileComponents( + initialSource, + deltaSource, + ); + expect( + () => deltaInspector.compareGenerations(initial, delta), + returnsNormally, + ); + final repo = + delta.metadata[hotReloadLibraryMetadataTag] + as HotReloadLibraryMetadataRepository; repo.mapToIndexedNodes(LibraryIndex.all(delta)); - final metadata = repo.mapping[delta.libraries - .firstWhere((l) => l.importUri.toString() == 'memory:///main.dart')]!; - expect(metadata.deletedStaticProcedureNames, - orderedEquals(['deletedSetter'])); + final metadata = + repo.mapping[delta.libraries.firstWhere( + (l) => l.importUri.toString() == 'memory:///main.dart', + )]!; + expect( + metadata.deletedStaticProcedureNames, + orderedEquals(['deletedSetter']), + ); }); }); group('Non-hot-reloadable packages ', () { final packageName = 'test_package'; - final deltaInspector = - HotReloadDeltaInspector(nonHotReloadablePackages: {packageName}); + final deltaInspector = HotReloadDeltaInspector( + nonHotReloadablePackages: {packageName}, + ); test('reject reloads when a member is added.', () async { - final initialAndDeltaSource = ''' + final initialAndDeltaSource = + ''' import 'package:$packageName/file.dart'; main() {} '''; @@ -369,15 +418,17 @@ packageName: packageName, ); expect( - deltaInspector.compareGenerations(initial, delta), - unorderedEquals([ - 'Attempting to hot reload a modified library from a package ' - 'marked as non-hot-reloadable: ' - "Library: 'package:$packageName/file.dart'" - ])); + deltaInspector.compareGenerations(initial, delta), + unorderedEquals([ + 'Attempting to hot reload a modified library from a package ' + 'marked as non-hot-reloadable: ' + "Library: 'package:$packageName/file.dart'", + ]), + ); }); test('reject reloads when a member is removed.', () async { - final initialAndDeltaSource = ''' + final initialAndDeltaSource = + ''' import 'package:$packageName/file.dart'; main() {} '''; @@ -391,19 +442,21 @@ packageName: packageName, ); expect( - deltaInspector.compareGenerations(initial, delta), - unorderedEquals([ - 'Attempting to hot reload a modified library from a package ' - 'marked as non-hot-reloadable: ' - "Library: 'package:$packageName/file.dart'" - ])); + deltaInspector.compareGenerations(initial, delta), + unorderedEquals([ + 'Attempting to hot reload a modified library from a package ' + 'marked as non-hot-reloadable: ' + "Library: 'package:$packageName/file.dart'", + ]), + ); }); test('accept reloads when introduced but not modified.', () async { final initialSource = ''' main() {} '''; final initialAndDeltaPackageSource = 'class Foo { int member = 100; }'; - final deltaSource = ''' + final deltaSource = + ''' import 'package:$packageName/file.dart'; main() {} '''; @@ -414,8 +467,10 @@ deltaPackageSource: initialAndDeltaPackageSource, packageName: packageName, ); - expect(() => deltaInspector.compareGenerations(initial, delta), - returnsNormally); + expect( + () => deltaInspector.compareGenerations(initial, delta), + returnsNormally, + ); }); }); } @@ -428,11 +483,13 @@ /// whose source contents across one generation are [initialPackageSource] and /// [deltaPackageSource]. Future<({Component initial, Component delta})> compileComponents( - String initialSource, String deltaSource, - {Uri? baseUri, - String? packageName, - String initialPackageSource = '', - String deltaPackageSource = ''}) async { + String initialSource, + String deltaSource, { + Uri? baseUri, + String? packageName, + String initialPackageSource = '', + String deltaPackageSource = '', +}) async { baseUri ??= memoryDirectory; final fileName = 'main.dart'; @@ -444,8 +501,9 @@ Uri? packageConfigUri; if (packageName != null) { packageConfigUri = baseUri.resolve('package_config.json'); - memoryFileMap['package_config.json'] = - generateFakePackagesFile(packageName: packageName); + memoryFileMap['package_config.json'] = generateFakePackagesFile( + packageName: packageName, + ); memoryFileMap[packageFileName] = initialPackageSource; } final initialResult = await incrementalComponentFromMemory( @@ -454,8 +512,11 @@ baseUri: baseUri, packageConfigUri: packageConfigUri, ); - expect(initialResult.errors, isEmpty, - reason: 'Initial source produced compile time errors.'); + expect( + initialResult.errors, + isEmpty, + reason: 'Initial source produced compile time errors.', + ); memoryFileMap[fileName] = deltaSource; if (packageName != null) { @@ -468,11 +529,14 @@ packageConfigUri: packageConfigUri, initialCompilerState: initialResult.initialCompilerState, ); - expect(deltaResult.errors, isEmpty, - reason: 'Delta source produced compile time errors.'); + expect( + deltaResult.errors, + isEmpty, + reason: 'Delta source produced compile time errors.', + ); return ( initial: initialResult.ddcResult.component, - delta: deltaResult.ddcResult.component + delta: deltaResult.ddcResult.component, ); }
diff --git a/pkg/dev_compiler/test/hot_reload_suite.dart b/pkg/dev_compiler/test/hot_reload_suite.dart index fbc3a96..b63d204 100644 --- a/pkg/dev_compiler/test/hot_reload_suite.dart +++ b/pkg/dev_compiler/test/hot_reload_suite.dart
@@ -11,7 +11,8 @@ import 'package:_fe_analyzer_shared/src/util/relativize.dart' as fe_shared; import 'package:args/args.dart'; import 'package:collection/collection.dart'; -import 'package:dev_compiler/dev_compiler.dart' as ddc_names +import 'package:dev_compiler/dev_compiler.dart' + as ddc_names show libraryUriToJsIdentifier; import 'package:front_end/src/api_unstable/ddc.dart' as fe; import 'package:path/path.dart' as p; @@ -69,44 +70,63 @@ }); static final _parser = ArgParser() - ..addFlag('help', - abbr: 'h', - help: 'Display this message.', - negatable: false, - defaultsTo: false) - ..addOption('runtime', - abbr: 'r', - defaultsTo: 'd8', - allowed: RuntimePlatforms.values.map((v) => v.text), - help: 'runtime platform used to run tests.') - ..addOption('named-configuration', - abbr: 'n', - defaultsTo: 'no-configuration', - help: 'configuration name to use for emitting test result files.') - ..addOption('output-directory', - help: 'directory to emit test results files.') - ..addOption('filter', - abbr: 'f', defaultsTo: r'.*', help: 'regexp filter over tests to run.') - ..addOption('diff', - allowed: ['check', 'write', 'ignore'], - allowedHelp: { - 'check': 'validate that reload test diffs are generated and correct.', - 'write': 'write diffs for reload tests.', - 'ignore': 'ignore reload diffs.', - }, - defaultsTo: 'check', - help: 'selects whether test diffs should be checked, written, or ' - 'ignored.') - ..addFlag('debug', - abbr: 'd', - defaultsTo: false, - negatable: true, - help: 'enables additional debug behavior and logging.') - ..addFlag('verbose', - abbr: 'v', - defaultsTo: true, - negatable: true, - help: 'enables verbose logging.'); + ..addFlag( + 'help', + abbr: 'h', + help: 'Display this message.', + negatable: false, + defaultsTo: false, + ) + ..addOption( + 'runtime', + abbr: 'r', + defaultsTo: 'd8', + allowed: RuntimePlatforms.values.map((v) => v.text), + help: 'runtime platform used to run tests.', + ) + ..addOption( + 'named-configuration', + abbr: 'n', + defaultsTo: 'no-configuration', + help: 'configuration name to use for emitting test result files.', + ) + ..addOption( + 'output-directory', + help: 'directory to emit test results files.', + ) + ..addOption( + 'filter', + abbr: 'f', + defaultsTo: r'.*', + help: 'regexp filter over tests to run.', + ) + ..addOption( + 'diff', + allowed: ['check', 'write', 'ignore'], + allowedHelp: { + 'check': 'validate that reload test diffs are generated and correct.', + 'write': 'write diffs for reload tests.', + 'ignore': 'ignore reload diffs.', + }, + defaultsTo: 'check', + help: + 'selects whether test diffs should be checked, written, or ' + 'ignored.', + ) + ..addFlag( + 'debug', + abbr: 'd', + defaultsTo: false, + negatable: true, + help: 'enables additional debug behavior and logging.', + ) + ..addFlag( + 'verbose', + abbr: 'v', + defaultsTo: true, + negatable: true, + help: 'enables verbose logging.', + ); /// Usage description for these command line options. String get usage => _parser.usage; @@ -173,16 +193,21 @@ /// generation. final Map<int, bool> isHotRestart; - HotReloadTest(this.directory, this.name, this.generationCount, this.files, - ReloadTestConfiguration config, this.isHotRestart) - : excludedPlatforms = config.excludedPlatforms, - expectedErrors = config.expectedErrors; + HotReloadTest( + this.directory, + this.name, + this.generationCount, + this.files, + ReloadTestConfiguration config, + this.isHotRestart, + ) : excludedPlatforms = config.excludedPlatforms, + expectedErrors = config.expectedErrors; /// The files edited in the provided [generation] (zero-based). List<TestFile> filesEditedInGeneration(int generation) => [ - for (final file in files) - if (file._editsByGeneration.containsKey(generation)) file - ]; + for (final file in files) + if (file._editsByGeneration.containsKey(generation)) file, + ]; } /// An individual test file for a hot reload test across all generations. @@ -238,32 +263,37 @@ /// The directory containing files emitted from Frontend Server compiles and /// recompiles. - late final Directory frontendServerEmittedFilesDir = - Directory.fromUri(generatedCodeDir.uri.resolve('.fes/'))..createSync(); + late final Directory frontendServerEmittedFilesDir = Directory.fromUri( + generatedCodeDir.uri.resolve('.fes/'), + )..createSync(); /// The output location for .dill file created by the front end server. - late final Uri outputDillUri = - frontendServerEmittedFilesDir.uri.resolve('output.dill'); + late final Uri outputDillUri = frontendServerEmittedFilesDir.uri.resolve( + 'output.dill', + ); /// The output location for the incremental .dill file created by the front /// end server. - late final Uri outputIncrementalDillUri = - frontendServerEmittedFilesDir.uri.resolve('output_incremental.dill'); + late final Uri outputIncrementalDillUri = frontendServerEmittedFilesDir.uri + .resolve('output_incremental.dill'); /// All test results that are reported after running the entire test suite. final List<TestResultOutcome> testOutcomes = []; /// The directory used as a temporary staging area to construct a compile-able /// test app across reload/restart generations. - late final Directory snapshotDir = - Directory.fromUri(generatedCodeDir.uri.resolve('.snapshot/')) - ..createSync(); + late final Directory snapshotDir = Directory.fromUri( + generatedCodeDir.uri.resolve('.snapshot/'), + )..createSync(); // TODO(markzipan): Support custom entrypoints. late final Uri snapshotEntrypointUri = snapshotDir.uri.resolve('main.dart'); late final String snapshotEntrypointWithScheme = () { final snapshotEntrypointLibraryName = fe_shared.relativizeUri( - snapshotDir.uri, snapshotEntrypointUri, fe_shared.isWindows); + snapshotDir.uri, + snapshotEntrypointUri, + fe_shared.isWindows, + ); return '$filesystemScheme:///$snapshotEntrypointLibraryName'; }(); @@ -278,41 +308,54 @@ // TODO(nshahan): report time for collecting and validating test sources. final testSuite = collectTestSources(options); _debugPrint( - 'See generated hot reload framework code in ${generatedCodeDir.uri}'); + 'See generated hot reload framework code in ${generatedCodeDir.uri}', + ); final controller = createFrontEndServer(); for (final test in testSuite) { stopwatch ..start() ..reset(); diffCheck(test); - final tempDirectory = - Directory.fromUri(generatedCodeDir.uri.resolve('${test.name}/')) - ..createSync(); + final tempDirectory = Directory.fromUri( + generatedCodeDir.uri.resolve('${test.name}/'), + )..createSync(); if (options.runtime.emitsJS) { filesystem = HotReloadMemoryFilesystem(tempDirectory.uri); } var compileSuccess = false; _print('Generating test assets.', label: test.name); // TODO(markzipan): replace this with a test-configurable main entrypoint. - final mainDartFilePath = - test.directory.uri.resolve('main.dart').toFilePath(); + final mainDartFilePath = test.directory.uri + .resolve('main.dart') + .toFilePath(); _debugPrint('Test entrypoint: $mainDartFilePath', label: test.name); - _print('Generating code over ${test.generationCount} generations.', - label: test.name); + _print( + 'Generating code over ${test.generationCount} generations.', + label: test.name, + ); stopwatch ..start() ..reset(); - for (var generation = 0; - generation < test.generationCount; - generation++) { + for ( + var generation = 0; + generation < test.generationCount; + generation++ + ) { final updatedFiles = copyGenerationSources(test, generation); compileSuccess = await compileGeneration( - test, generation, tempDirectory, updatedFiles, controller); + test, + generation, + tempDirectory, + updatedFiles, + controller, + ); if (!compileSuccess) break; } if (!compileSuccess) { - _print('Did not emit all assets due to compilation error.', - label: test.name); + _print( + 'Did not emit all assets due to compilation error.', + label: test.name, + ); // Skip to the next test and avoid execution if there is an unexpected // compilation error. continue; @@ -324,9 +367,15 @@ .transform(utf8.decoder) .listen(testOutputBuffer.write); final testPassed = await runTest( - test, tempDirectory, IOSink(testOutputStreamController.sink)); + test, + tempDirectory, + IOSink(testOutputStreamController.sink), + ); await reportTestOutcome( - test.name, testOutputBuffer.toString(), testPassed); + test.name, + testOutputBuffer.toString(), + testPassed, + ); } await shutdown(controller); await reportAllResults(); @@ -376,15 +425,16 @@ // Set an arbitrary cap on generations. final globalMaxGenerations = 100; final validTestSourceName = RegExp( - // Begins with 1 or more word characters. - r'^(?<name>[\w,-]+)' - // Followed by a dot and 1 or more digits. - r'\.(?<generation>\d+)' - // Optionally a dot and either the word 'restart' indicating a hot - // restart, or the word 'reject', indicating a hot reload rejection. - r'((?<restart>\.restart)|(?<reject>\.reject))?' - // Ending with a dot and the word 'dart' - r'\.dart$'); + // Begins with 1 or more word characters. + r'^(?<name>[\w,-]+)' + // Followed by a dot and 1 or more digits. + r'\.(?<generation>\d+)' + // Optionally a dot and either the word 'restart' indicating a hot + // restart, or the word 'reject', indicating a hot reload rejection. + r'((?<restart>\.restart)|(?<reject>\.reject))?' + // Ending with a dot and the word 'dart' + r'\.dart$', + ); final testSuite = <HotReloadTest>[]; for (var testDir in Directory.fromUri(allTestsUri).listSync()) { if (testDir is! Directory) { @@ -392,8 +442,10 @@ // Ignore Dart source files, which may be imported as helpers. continue; } - throw Exception('Non-directory or file entity found in ' - '${allTestsUri.toFilePath()}: $testDir'); + throw Exception( + 'Non-directory or file entity found in ' + '${allTestsUri.toFilePath()}: $testDir', + ); } final testDirParts = testDir.uri.pathSegments; final testName = testDirParts[testDirParts.length - 2]; @@ -410,24 +462,28 @@ : ReloadTestConfiguration(); if (testConfig.excludedPlatforms.contains(options.runtime)) { // Skip this test directory if this platform is excluded. - _print('Skipping test on platform: ${options.runtime.text}', - label: testName); + _print( + 'Skipping test on platform: ${options.runtime.text}', + label: testName, + ); continue; } final isHotRestart = <int, bool>{}; final expectedErrors = testConfig.expectedErrors; - final dartFiles = testDir - .listSync() - .where((e) => e is File && e.uri.path.endsWith('.dart')); + final dartFiles = testDir.listSync().where( + (e) => e is File && e.uri.path.endsWith('.dart'), + ); // All files in this test clustered by file name - in generation order. final filesByGeneration = <String, PriorityQueue<TestFileEdit>>{}; for (final file in dartFiles) { final fileName = p.basename(file.uri.toFilePath()); final matches = validTestSourceName.allMatches(fileName); if (matches.length != 1) { - throw Exception('Invalid test source file name: $fileName\n' - 'Valid names look like "file_name.10.dart", ' - '"file_name.10.restart.dart" or "file_name.10.reject.dart".'); + throw Exception( + 'Invalid test source file name: $fileName\n' + 'Valid names look like "file_name.10.dart", ' + '"file_name.10.restart.dart" or "file_name.10.reject.dart".', + ); } final match = matches.single; final name = match.namedGroup('name'); @@ -439,58 +495,80 @@ isHotRestart[generation] = restart; } else { if (restart != isHotRestart[generation]) { - throw Exception('Expected all files for generation $generation to ' - "be consistent about having a '.restart' suffix, but $fileName " - 'does not match other files in the same generation.'); + throw Exception( + 'Expected all files for generation $generation to ' + "be consistent about having a '.restart' suffix, but $fileName " + 'does not match other files in the same generation.', + ); } } final rejectExpected = match.namedGroup('reject') != null; assert(!(rejectExpected && restart)); if (rejectExpected && !expectedErrors.containsKey(generation)) { throw Exception( - 'Expected error for generation file missing from config.json: ' - '$fileName'); + 'Expected error for generation file missing from config.json: ' + '$fileName', + ); } if (!rejectExpected && expectedErrors.containsKey(generation)) { throw Exception( - 'Error for generation $generation found in config.json: ' - '"${expectedErrors[generation]}"\n' - 'Either remove the error or update the name of this file: ' - '$fileName -> ' - '$name.$generation.reject.dart'); + 'Error for generation $generation found in config.json: ' + '"${expectedErrors[generation]}"\n' + 'Either remove the error or update the name of this file: ' + '$fileName -> ' + '$name.$generation.reject.dart', + ); } if (generation == 0 && rejectExpected) { - throw Exception('The first generation may not be rejected: ' - '$fileName'); + throw Exception( + 'The first generation may not be rejected: ' + '$fileName', + ); } filesByGeneration .putIfAbsent( - restoredName, - () => PriorityQueue((TestFileEdit a, TestFileEdit b) => - a.generation - b.generation)) + restoredName, + () => PriorityQueue( + (TestFileEdit a, TestFileEdit b) => a.generation - b.generation, + ), + ) .add(TestFileEdit(generation, file.uri)); } if (maxGenerations > globalMaxGenerations) { - throw Exception('Too many generations specified in test ' - '(requested: $maxGenerations, max: $globalMaxGenerations).'); + throw Exception( + 'Too many generations specified in test ' + '(requested: $maxGenerations, max: $globalMaxGenerations).', + ); } final testFiles = <TestFile>[]; for (final entry in filesByGeneration.entries) { final fileName = entry.key; final fileEdits = entry.value.toList(); - final editsByGeneration = LinkedHashMap<int, TestFileEdit>.from( - {for (final edit in fileEdits) edit.generation: edit}); + final editsByGeneration = LinkedHashMap<int, TestFileEdit>.from({ + for (final edit in fileEdits) edit.generation: edit, + }); testFiles.add(TestFile(fileName, editsByGeneration)); } - testSuite.add(HotReloadTest(testDir, testName, maxGenerations + 1, - testFiles, testConfig, isHotRestart)); + testSuite.add( + HotReloadTest( + testDir, + testName, + maxGenerations + 1, + testFiles, + testConfig, + isHotRestart, + ), + ); } return testSuite; } /// Report results for this test's execution. Future<void> reportTestOutcome( - String testName, String testOutput, bool testPassed) async { + String testName, + String testOutput, + bool testPassed, + ) async { stopwatch.stop(); final outcome = TestResultOutcome( configuration: options.namedConfiguration, @@ -509,7 +587,11 @@ /// Report results for this test's sources' diff validations. void reportDiffOutcome( - String testName, Uri fileUri, String testOutput, bool testPassed) { + String testName, + Uri fileUri, + String testOutput, + bool testPassed, + ) { stopwatch.stop(); final filePath = fileUri.path; final relativeFilePath = p.relative(filePath, from: allTestsUri.path); @@ -522,11 +604,15 @@ outcome.matchedExpectations = testPassed; testOutcomes.add(outcome); if (testPassed) { - _debugPrint('PASSED (diff on $filePath) with:\n $testOutput', - label: testName); + _debugPrint( + 'PASSED (diff on $filePath) with:\n $testOutput', + label: testName, + ); } else { - _debugPrint('FAILED (diff on $filePath) with:\n $testOutput', - label: testName); + _debugPrint( + 'FAILED (diff on $filePath) with:\n $testOutput', + label: testName, + ); } } @@ -534,31 +620,44 @@ void diffCheck(HotReloadTest test) { var diffMode = options.diffMode; if (fe_shared.isWindows && diffMode != DiffMode.ignore) { - _print("Diffing isn't supported on Windows. Defaulting to 'ignore'.", - label: test.name); + _print( + "Diffing isn't supported on Windows. Defaulting to 'ignore'.", + label: test.name, + ); diffMode = DiffMode.ignore; } switch (diffMode) { case DiffMode.check: _print('Checking source file diffs.', label: test.name); for (final file in test.files) { - _debugPrint('Checking source file diffs for $file.', - label: test.name); + _debugPrint( + 'Checking source file diffs for $file.', + label: test.name, + ); var edits = file.edits.iterator; if (!edits.moveNext()) { throw Exception('Test file created with no generation edits.'); } var currentEdit = edits.current; // Check that the first file does not have a diff. - var (currentCode, currentDiff) = - _splitTestByDiff(currentEdit.fileUri); + var (currentCode, currentDiff) = _splitTestByDiff( + currentEdit.fileUri, + ); var diffCount = testDiffSeparator.allMatches(currentDiff).length; if (diffCount == 0) { - reportDiffOutcome(test.name, currentEdit.fileUri, - 'First generation does not have a diff', true); + reportDiffOutcome( + test.name, + currentEdit.fileUri, + 'First generation does not have a diff', + true, + ); } else { - reportDiffOutcome(test.name, currentEdit.fileUri, - 'First generation should not have any diffs', false); + reportDiffOutcome( + test.name, + currentEdit.fileUri, + 'First generation should not have any diffs', + false, + ); } while (edits.moveNext()) { final previousEdit = currentEdit; @@ -568,16 +667,21 @@ // Check that exactly one diff exists. diffCount = testDiffSeparator.allMatches(currentDiff).length; if (diffCount == 0) { - reportDiffOutcome(test.name, currentEdit.fileUri, - 'No diff found for ${currentEdit.fileUri}', false); + reportDiffOutcome( + test.name, + currentEdit.fileUri, + 'No diff found for ${currentEdit.fileUri}', + false, + ); continue; } else if (diffCount > 1) { reportDiffOutcome( - test.name, - currentEdit.fileUri, - 'Too many diffs found for ${currentEdit.fileUri} ' - '(expected 1)', - false); + test.name, + currentEdit.fileUri, + 'Too many diffs found for ${currentEdit.fileUri} ' + '(expected 1)', + false, + ); continue; } // Check that the diff is properly generated. @@ -586,9 +690,10 @@ if (file.baseName != 'main.dart' && previousCode == currentCode) { // TODO(markzipan): Should we make this an error? _print( - 'Extraneous file detected. ${currentEdit.fileUri} ' - 'is identical to ${previousEdit.fileUri} and can be removed.', - label: test.name); + 'Extraneous file detected. ${currentEdit.fileUri} ' + 'is identical to ${previousEdit.fileUri} and can be removed.', + label: test.name, + ); } final previousTempUri = generatedCodeDir.uri.resolve('__previous'); final currentTempUri = generatedCodeDir.uri.resolve('__current'); @@ -597,41 +702,53 @@ File.fromUri(previousTempUri).writeAsStringSync('$previousCode\n'); File.fromUri(currentTempUri).writeAsStringSync('$currentCode\n'); final diffOutput = _diffWithFileUris( - previousTempUri, currentTempUri, - label: test.name); + previousTempUri, + currentTempUri, + label: test.name, + ); File.fromUri(previousTempUri).deleteSync(); File.fromUri(currentTempUri).deleteSync(); if (diffOutput != currentDiff) { reportDiffOutcome( - test.name, - currentEdit.fileUri, - 'Unexpected diff found for ${currentEdit.fileUri}:\n' - '-- Expected --\n$diffOutput\n' - '-- Actual --\n$currentDiff', - false); + test.name, + currentEdit.fileUri, + 'Unexpected diff found for ${currentEdit.fileUri}:\n' + '-- Expected --\n$diffOutput\n' + '-- Actual --\n$currentDiff', + false, + ); } else { - reportDiffOutcome(test.name, currentEdit.fileUri, - 'Correct diff found for ${currentEdit.fileUri}', true); + reportDiffOutcome( + test.name, + currentEdit.fileUri, + 'Correct diff found for ${currentEdit.fileUri}', + true, + ); } } } case DiffMode.write: _print('Generating source file diffs.', label: test.name); for (final file in test.files) { - _debugPrint('Generating source file diffs for ${file.edits}.', - label: test.name); + _debugPrint( + 'Generating source file diffs for ${file.edits}.', + label: test.name, + ); var edits = file.edits.iterator; if (!edits.moveNext()) { throw Exception('Test file created with no generation edits.'); } var currentEdit = edits.current; - var (currentCode, currentDiff) = - _splitTestByDiff(currentEdit.fileUri); + var (currentCode, currentDiff) = _splitTestByDiff( + currentEdit.fileUri, + ); // Don't generate a diff for the first file of any generation, // and delete any diffs encountered. if (currentDiff.isNotEmpty) { - _print('Removing extraneous diff from ${currentEdit.fileUri}', - label: test.name); + _print( + 'Removing extraneous diff from ${currentEdit.fileUri}', + label: test.name, + ); File.fromUri(currentEdit.fileUri).writeAsStringSync(currentCode); } while (edits.moveNext()) { @@ -645,19 +762,27 @@ File.fromUri(previousTempUri).writeAsStringSync('$previousCode\n'); File.fromUri(currentTempUri).writeAsStringSync('$currentCode\n'); final diffOutput = _diffWithFileUris( - previousTempUri, currentTempUri, - label: test.name); + previousTempUri, + currentTempUri, + label: test.name, + ); File.fromUri(previousTempUri).deleteSync(); File.fromUri(currentTempUri).deleteSync(); // Write an empty line between the code and the diff comment to // agree with the dart formatter. final newCurrentText = '$currentCode\n\n$diffOutput\n'; File.fromUri(currentEdit.fileUri).writeAsStringSync(newCurrentText); - _print('Writing updated diff to $currentEdit.fileUri', - label: test.name); + _print( + 'Writing updated diff to $currentEdit.fileUri', + label: test.name, + ); _debugPrint('Updated diff:\n$diffOutput', label: test.name); - reportDiffOutcome(test.name, currentEdit.fileUri, - 'diff updated for $currentEdit.fileUri', true); + reportDiffOutcome( + test.name, + currentEdit.fileUri, + 'diff updated for $currentEdit.fileUri', + true, + ); } } case DiffMode.ignore: @@ -665,8 +790,10 @@ for (final file in test.files) { for (final edit in file.edits) { var uri = edit.fileUri; - _debugPrint('Ignoring source file diffs for $uri.', - label: test.name); + _debugPrint( + 'Ignoring source file diffs for $uri.', + label: test.name, + ); reportDiffOutcome(test.name, uri, 'Ignoring diff for $uri', true); } } @@ -678,25 +805,31 @@ /// /// If no reload receipt is found the line is passed to [orElse]. [test] is /// only used to label debug logs. - void parseReloadReceipt(HotReloadTest test, String line, - Function(HotReloadReceipt) onReloadReceipt, Function(String) orElse) { + void parseReloadReceipt( + HotReloadTest test, + String line, + Function(HotReloadReceipt) onReloadReceipt, + Function(String) orElse, + ) { if (line.startsWith(HotReloadReceipt.hotReloadReceiptTag)) { // Reload utils write reload receipts as output lines with a leading tag // so the lines can be extracted here. - final reloadReceipt = HotReloadReceipt.fromJson(jsonDecode( - line.substring(HotReloadReceipt.hotReloadReceiptTag.length)) - as Map<String, dynamic>); + final reloadReceipt = HotReloadReceipt.fromJson( + jsonDecode(line.substring(HotReloadReceipt.hotReloadReceiptTag.length)) + as Map<String, dynamic>, + ); onReloadReceipt(reloadReceipt); _debugPrint( - [ - 'Generation ${reloadReceipt.generation} ' - 'was ${reloadReceipt.status.name}', - if (reloadReceipt.status == Status.rejected) - ': "${reloadReceipt.rejectionMessage}"' - else - '.', - ].join(), - label: test.name); + [ + 'Generation ${reloadReceipt.generation} ' + 'was ${reloadReceipt.status.name}', + if (reloadReceipt.status == Status.rejected) + ': "${reloadReceipt.rejectionMessage}"' + else + '.', + ].join(), + label: test.name, + ); } else { orElse(line); } @@ -709,16 +842,19 @@ /// reported, the test still ran through all expected generations with the /// expected accept/reject/restart status. bool reloadReceiptCheck( - HotReloadTest test, List<HotReloadReceipt> reloadReceipts) { + HotReloadTest test, + List<HotReloadReceipt> reloadReceipts, + ) { // Check number of reloads. // No reload receipt will appear for generation 0. final expectedReloadCount = test.generationCount - 1; if (reloadReceipts.length != expectedReloadCount) { _print( - 'Unexpected number of reloads/restarts were performed. ' - 'Expected: $expectedReloadCount Actual: ${reloadReceipts.length}\n' - '${reloadReceipts.join('\n')}', - label: test.name); + 'Unexpected number of reloads/restarts were performed. ' + 'Expected: $expectedReloadCount Actual: ${reloadReceipts.length}\n' + '${reloadReceipts.join('\n')}', + label: test.name, + ); return false; } var expectedGeneration = 0; @@ -727,46 +863,51 @@ // Validate order of reloads. if (reloadReceipt.generation != expectedGeneration) { _print( - 'Generation reload order mismatch. ' - 'Expected: $expectedGeneration ' - 'Actual: ${reloadReceipt.generation}\n' - '${reloadReceipts.join('\n')}', - label: test.name); + 'Generation reload order mismatch. ' + 'Expected: $expectedGeneration ' + 'Actual: ${reloadReceipt.generation}\n' + '${reloadReceipts.join('\n')}', + label: test.name, + ); return false; } final expectedError = test.expectedErrors[reloadReceipt.generation]; // Check the reloads match the expected accept/reject. if (reloadReceipt.status == Status.accepted && expectedError != null) { _print( - 'Generation ${reloadReceipt.generation} was not rejected. ' - 'Expected: $expectedError', - label: test.name); + 'Generation ${reloadReceipt.generation} was not rejected. ' + 'Expected: $expectedError', + label: test.name, + ); return false; } if (reloadReceipt.status == Status.rejected) { if (expectedError == null) { _print( - 'Generation ${reloadReceipt.generation} was unexpectedly ' - 'rejected: ${reloadReceipt.rejectionMessage}', - label: test.name); + 'Generation ${reloadReceipt.generation} was unexpectedly ' + 'rejected: ${reloadReceipt.rejectionMessage}', + label: test.name, + ); return false; } final rejectionMessage = reloadReceipt.rejectionMessage; if (rejectionMessage == null || !rejectionMessage.contains(expectedError)) { _print( - 'Generation ${reloadReceipt.generation} was rejected but error ' - 'was unexpected. Expected: "$expectedError" Actual: ' - '${reloadReceipt.rejectionMessage}', - label: test.name); + 'Generation ${reloadReceipt.generation} was rejected but error ' + 'was unexpected. Expected: "$expectedError" Actual: ' + '${reloadReceipt.rejectionMessage}', + label: test.name, + ); return false; } } } _debugPrint( - 'Generation reloads matched expected outcomes:\n' - ' ${reloadReceipts.join('\n ')}', - label: test.name); + 'Generation reloads matched expected outcomes:\n' + ' ${reloadReceipts.join('\n ')}', + label: test.name, + ); return true; } @@ -782,23 +923,28 @@ // names restored (e.g., path/to/main' from 'path/to/main.0.dart). // TODO(markzipan): support subdirectories. _debugPrint( - 'Copying Dart files to snapshot directory: ' - '${snapshotDir.uri.toFilePath()}', - label: test.name); + 'Copying Dart files to snapshot directory: ' + '${snapshotDir.uri.toFilePath()}', + label: test.name, + ); for (final file in test.filesEditedInGeneration(generation)) { final fileSnapshotUri = snapshotDir.uri.resolve(file.baseName); final editUri = file.editForGeneration(generation).fileUri; File.fromUri(editUri).copySync(fileSnapshotUri.toFilePath()); final relativeSnapshotPath = fe_shared.relativizeUri( - snapshotDir.uri, fileSnapshotUri, fe_shared.isWindows); + snapshotDir.uri, + fileSnapshotUri, + fe_shared.isWindows, + ); final snapshotPathWithScheme = '$filesystemScheme:///$relativeSnapshotPath'; updatedFilesInCurrentGeneration.add(snapshotPathWithScheme); } _print( - 'Updated files in generation $generation: ' - '$updatedFilesInCurrentGeneration', - label: test.name); + 'Updated files in generation $generation: ' + '$updatedFilesInCurrentGeneration', + label: test.name, + ); return updatedFilesInCurrentGeneration; } @@ -808,11 +954,12 @@ /// /// Reports test failures on compile time errors. Future<bool> compileGeneration( - HotReloadTest test, - int generation, - Directory outputDirectory, - List<String> updatedFiles, - HotReloadFrontendServerController controller); + HotReloadTest test, + int generation, + Directory outputDirectory, + List<String> updatedFiles, + HotReloadFrontendServerController controller, + ); /// Runs [test] from compiled and generated assets in [tempDirectory] and /// returns `true` if it passes. @@ -820,7 +967,10 @@ /// All output (standard and errors) from running the test is written to /// [outputSink]. Future<bool> runTest( - HotReloadTest test, Directory tempDirectory, IOSink outputSink); + HotReloadTest test, + Directory tempDirectory, + IOSink outputSink, + ); /// Reports test results to standard out as well as the output .json file if /// requested. @@ -843,26 +993,33 @@ final testLogsUri = testResultsOutputDir.resolve('logs.json'); if (Platform.isWindows) { // TODO(55297): Logs are disabled on windows until this but is fixed. - _print('Logs are not written on Windows. ' - 'See: https://github.com/dart-lang/sdk/issues/55297'); + _print( + 'Logs are not written on Windows. ' + 'See: https://github.com/dart-lang/sdk/issues/55297', + ); } else { final testLogsSink = File.fromUri(testLogsUri).openWrite(); testOutcomeLogs.forEach(testLogsSink.writeln); await testLogsSink.flush(); await testLogsSink.close(); } - _print('Emitted logs to ${testResultsUri.toFilePath()} ' - 'and ${testLogsUri.toFilePath()}.'); + _print( + 'Emitted logs to ${testResultsUri.toFilePath()} ' + 'and ${testLogsUri.toFilePath()}.', + ); } if (testOutcomes.isEmpty) { - print('No tests ran: no sub-directories in ${allTestsUri.toFilePath()} ' - 'match the provided filter:\n' - '${options.testNameFilter}'); + print( + 'No tests ran: no sub-directories in ${allTestsUri.toFilePath()} ' + 'match the provided filter:\n' + '${options.testNameFilter}', + ); exit(0); } // Report failed tests. - var failedTests = - testOutcomes.where((outcome) => !outcome.matchedExpectations); + var failedTests = testOutcomes.where( + (outcome) => !outcome.matchedExpectations, + ); if (failedTests.isNotEmpty) { print('Some tests failed:'); failedTests.forEach((outcome) { @@ -877,14 +1034,19 @@ /// /// Will echo the commands to the console before running them when running in /// `verbose` mode. - Future<Process> startProcess(String name, String command, List<String> args, - {Map<String, String> environment = const {}, - ProcessStartMode mode = ProcessStartMode.normal}) { + Future<Process> startProcess( + String name, + String command, + List<String> args, { + Map<String, String> environment = const {}, + ProcessStartMode mode = ProcessStartMode.normal, + }) { if (options.verbose) { print('Running $name:\n$command ${args.join(' ')}\n'); if (environment.isNotEmpty) { - var environmentVariables = - environment.entries.map((e) => '${e.key}: ${e.value}').join('\n'); + var environmentVariables = environment.entries + .map((e) => '${e.key}: ${e.value}') + .join('\n'); print('With environment:\n$environmentVariables\n'); } } @@ -917,13 +1079,20 @@ /// /// If [trimHeaders] is set, the leading '+++' and '---' file headers will be /// removed. - String _diffWithFileUris(Uri file1, Uri file2, - {String label = '', bool commented = true, bool trimHeaders = true}) { + String _diffWithFileUris( + Uri file1, + Uri file2, { + String label = '', + bool commented = true, + bool trimHeaders = true, + }) { final file1Path = file1.toFilePath(); final file2Path = file2.toFilePath(); final diffArgs = ['diff', '-u', file1Path, file2Path]; - _debugPrint("Running diff with 'git diff ${diffArgs.join(' ')}'.", - label: label); + _debugPrint( + "Running diff with 'git diff ${diffArgs.join(' ')}'.", + label: label, + ); final diffProcess = Process.runSync('git', diffArgs); final errOutput = diffProcess.stderr as String; if (errOutput.isNotEmpty) { @@ -953,58 +1122,70 @@ /// Hot reload test suite runner for DDC specific behavior that is agnostic to /// the environment where the compiled code is eventually run. abstract class DdcSuiteRunner extends HotReloadSuiteRunner { - late final String entrypointLibraryExportName = - ddc_names.libraryUriToJsIdentifier(snapshotEntrypointUri); - final Uri dartSdkJSUri = - buildRootUri.resolve('gen/utils/ddc/canary/sdk/ddc/dart_sdk.js'); - final Uri ddcModuleLoaderJSUri = - sdkRoot.resolve('pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js'); + late final String entrypointLibraryExportName = ddc_names + .libraryUriToJsIdentifier(snapshotEntrypointUri); + final Uri dartSdkJSUri = buildRootUri.resolve( + 'gen/utils/ddc/canary/sdk/ddc/dart_sdk.js', + ); + final Uri ddcModuleLoaderJSUri = sdkRoot.resolve( + 'pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js', + ); final String ddcPlatformDillFromSdkRoot = fe_shared.relativizeUri( - sdkRoot, buildRootUri.resolve('ddc_outline.dill'), fe_shared.isWindows); + sdkRoot, + buildRootUri.resolve('ddc_outline.dill'), + fe_shared.isWindows, + ); final String entrypointModuleName = 'hot-reload-test:///main.dart'; DdcSuiteRunner(super.options); @override List<String> get platformFrontEndServerArgs => [ - '--dartdevc-module-format=ddc', - '--dartdevc-canary', - '--platform=$ddcPlatformDillFromSdkRoot', - '--target=dartdevc', - ]; + '--dartdevc-module-format=ddc', + '--dartdevc-canary', + '--platform=$ddcPlatformDillFromSdkRoot', + '--target=dartdevc', + ]; @override Future<bool> compileGeneration( - HotReloadTest test, - int generation, - Directory outputDirectory, - List<String> updatedFiles, - HotReloadFrontendServerController controller) async { + HotReloadTest test, + int generation, + Directory outputDirectory, + List<String> updatedFiles, + HotReloadFrontendServerController controller, + ) async { // The first generation calls `compile`, but subsequent ones call // `recompile`. // Likewise, use the incremental output file for `recompile` calls. // TODO(nshahan): Sending compile/recompile instructions is likely // the same across backends and should be shared code. String outputDillPath; - _print('Compiling generation $generation with the Frontend Server.', - label: test.name); + _print( + 'Compiling generation $generation with the Frontend Server.', + label: test.name, + ); CompilerOutput compilerOutput; if (generation == 0) { _debugPrint( - 'Compiling snapshot entrypoint: $snapshotEntrypointWithScheme', - label: test.name); + 'Compiling snapshot entrypoint: $snapshotEntrypointWithScheme', + label: test.name, + ); outputDillPath = outputDillUri.toFilePath(); - compilerOutput = - await controller.sendCompile(snapshotEntrypointWithScheme); + compilerOutput = await controller.sendCompile( + snapshotEntrypointWithScheme, + ); } else { _debugPrint( - 'Recompiling snapshot entrypoint: $snapshotEntrypointWithScheme', - label: test.name); + 'Recompiling snapshot entrypoint: $snapshotEntrypointWithScheme', + label: test.name, + ); outputDillPath = outputIncrementalDillUri.toFilePath(); compilerOutput = await controller.sendRecompile( - snapshotEntrypointWithScheme, - invalidatedFiles: updatedFiles, - recompileRestart: test.isHotRestart[generation]!); + snapshotEntrypointWithScheme, + invalidatedFiles: updatedFiles, + recompileRestart: test.isHotRestart[generation]!, + ); } final expectedError = test.expectedErrors[generation]; if (compilerOutput.errorCount > 0) { @@ -1015,9 +1196,10 @@ // If the failure was an expected rejection it is OK to continue // compiling generations and run the test. _debugPrint( - 'DDC rejected generation $generation: ' - '"${compilerOutput.outputText}"', - label: test.name); + 'DDC rejected generation $generation: ' + '"${compilerOutput.outputText}"', + label: test.name, + ); // Remove the expected error from this test to avoid expecting it to // appear as a rejection at runtime. test.expectedErrors[generation] = @@ -1026,9 +1208,10 @@ } else { // Fail if the error was unexpected. await reportTestOutcome( - test.name, - 'Test failed with compile error: ${compilerOutput.outputText}', - false); + test.name, + 'Test failed with compile error: ${compilerOutput.outputText}', + false, + ); return false; } } else { @@ -1038,30 +1221,42 @@ if (expectedError != null) { // A rejection error was expected but not seen. await reportTestOutcome( - test.name, - 'Missing rejection for generation $generation. ' - 'Expected: "$expectedError"', - false); + test.name, + 'Missing rejection for generation $generation. ' + 'Expected: "$expectedError"', + false, + ); return false; } _debugPrint( - 'Frontend Server successfully compiled outputs to: ' - '$outputDillPath', - label: test.name); - _debugPrint('Emitting JS code to ${outputDirectory.path}.', - label: test.name); + 'Frontend Server successfully compiled outputs to: ' + '$outputDillPath', + label: test.name, + ); + _debugPrint( + 'Emitting JS code to ${outputDirectory.path}.', + label: test.name, + ); // Update the memory filesystem with the newly-created JS files. - _print('Loading generation $generation files into the memory filesystem.', - label: test.name); + _print( + 'Loading generation $generation files into the memory filesystem.', + label: test.name, + ); final codeFile = File('$outputDillPath.sources'); final manifestFile = File('$outputDillPath.json'); final sourcemapFile = File('$outputDillPath.map'); - filesystem!.update(codeFile, manifestFile, sourcemapFile, - generation: '$generation'); + filesystem!.update( + codeFile, + manifestFile, + sourcemapFile, + generation: '$generation', + ); // Write JS files and sourcemaps to their respective generation. _print('Writing generation $generation assets.', label: test.name); - _debugPrint('Writing JS assets to ${outputDirectory.path}', - label: test.name); + _debugPrint( + 'Writing JS assets to ${outputDirectory.path}', + label: test.name, + ); filesystem!.writeToDisk(outputDirectory.uri, generation: '$generation'); return true; } @@ -1074,10 +1269,14 @@ @override Future<bool> runTest( - HotReloadTest test, Directory tempDirectory, IOSink outputSink) async { + HotReloadTest test, + Directory tempDirectory, + IOSink outputSink, + ) async { _print('Creating D8 hot reload test suite.', label: test.name); - final bootstrapJSUri = - tempDirectory.uri.resolve('generation0/bootstrap.js'); + final bootstrapJSUri = tempDirectory.uri.resolve( + 'generation0/bootstrap.js', + ); _print('Preparing to run D8 test.', label: test.name); final d8BootstrapJS = ddc_helpers.generateD8Bootstrapper( ddcModuleLoaderJsPath: escapedString(ddcModuleLoaderJSUri.toFilePath()), @@ -1096,11 +1295,19 @@ final process = await startProcess('D8', config.binary.toFilePath(), [ config.sealNativeObjectScript.toFilePath(), config.preamblesScript.toFilePath(), - bootstrapJSFile.path + bootstrapJSFile.path, ]); - process.stdout.transform(utf8.decoder).transform(LineSplitter()).listen( - (line) => parseReloadReceipt( - test, line, reloadReceipts.add, outputSink.writeln)); + process.stdout + .transform(utf8.decoder) + .transform(LineSplitter()) + .listen( + (line) => parseReloadReceipt( + test, + line, + reloadReceipts.add, + outputSink.writeln, + ), + ); return await process.exitCode == 0 && reloadReceiptCheck(test, reloadReceipts); } @@ -1113,7 +1320,10 @@ @override Future<bool> runTest( - HotReloadTest test, Directory tempDirectory, IOSink outputSink) async { + HotReloadTest test, + Directory tempDirectory, + IOSink outputSink, + ) async { // TODO(markzipan): Chrome tests are currently only configured for // debugging a single test instance. This is due to: // 1) Our tests not capturing test success/failure signals. These must be @@ -1122,14 +1332,18 @@ // 2) Chrome not closing after a test. We need to add logic to detect when // to either shut down Chrome or load the next test (reusing instances). _print('Creating Chrome hot reload test suite.', label: test.name); - final mainEntrypointJSUri = - tempDirectory.uri.resolve('generation0/main_module.bootstrap.js'); - final bootstrapJSUri = - tempDirectory.uri.resolve('generation0/bootstrap.js'); - final bootstrapHtmlUri = - tempDirectory.uri.resolve('generation0/index.html'); + final mainEntrypointJSUri = tempDirectory.uri.resolve( + 'generation0/main_module.bootstrap.js', + ); + final bootstrapJSUri = tempDirectory.uri.resolve( + 'generation0/bootstrap.js', + ); + final bootstrapHtmlUri = tempDirectory.uri.resolve( + 'generation0/index.html', + ); _print('Preparing to run Chrome test.', label: test.name); - var bootstrapHtml = ''' + var bootstrapHtml = + ''' <html> <head> <base href="/"> @@ -1139,23 +1353,28 @@ </body> </html> '''; - final entrypointLibraryExportName = - ddc_names.libraryUriToJsIdentifier(snapshotEntrypointUri); - final (chromeMainEntrypointJS, chromeBootstrapJS) = - ddc_helpers.generateChromeBootstrapperFiles( + final entrypointLibraryExportName = ddc_names.libraryUriToJsIdentifier( + snapshotEntrypointUri, + ); + final ( + chromeMainEntrypointJS, + chromeBootstrapJS, + ) = ddc_helpers.generateChromeBootstrapperFiles( ddcModuleLoaderJsPath: escapedString(ddcModuleLoaderJSUri.toFilePath()), dartSdkJsPath: escapedString(dartSdkJSUri.toFilePath()), entrypointModuleName: escapedString(entrypointModuleName), - mainModuleEntrypointJsPath: - escapedString(mainEntrypointJSUri.toFilePath()), + mainModuleEntrypointJsPath: escapedString( + mainEntrypointJSUri.toFilePath(), + ), entrypointLibraryExportName: escapedString(entrypointLibraryExportName), scriptDescriptors: filesystem!.scriptDescriptorForBootstrap, modifiedFilesPerGeneration: filesystem!.generationsToModifiedFilePaths, ); _debugPrint( - 'Writing Chrome bootstrap files: ' - '$mainEntrypointJSUri, $bootstrapJSUri, $bootstrapHtmlUri', - label: test.name); + 'Writing Chrome bootstrap files: ' + '$mainEntrypointJSUri, $bootstrapJSUri, $bootstrapHtmlUri', + label: test.name, + ); File.fromUri(mainEntrypointJSUri).writeAsStringSync(chromeMainEntrypointJS); File.fromUri(bootstrapJSUri).writeAsStringSync(chromeBootstrapJS); final bootstrapHtmlFile = File.fromUri(bootstrapHtmlUri) @@ -1165,77 +1384,88 @@ final config = ddc_helpers.ChromeConfiguration(sdkRoot); // Specifying '--user-data-dir' forces Chrome to not reuse an instance. final chromeDataDir = Directory.systemTemp.createTempSync(); - final process = await startProcess('Chrome', config.binary.toFilePath(), [ - '--no-first-run', - '--no-default-browser-check', - '--allow-file-access-from-files', - '--user-data-dir=${chromeDataDir.path}', - '--disable-default-apps', - '--disable-translate', - // These two flags are used to get the Chrome process to output messages - // to stderr so we can read the console.log messages. - // TODO(nshahan): Update if there is an easier way to get console.log - // messages. - '--enable-logging=stderr', - '--v=1', - bootstrapHtmlFile.path, - ]).then((process) { - StreamSubscription stdoutSubscription; - StreamSubscription stderrSubscription; - // The console.log messages in the output are prefixed with a header like: - // [42029:259:1126/154323.385793:INFO:CONSOLE(27547)] - final chromeConsoleLog = RegExp( - // Line starts with digits separated by ":", "." or "\"." - r'^\[[\d:\.\/]+' - // Followed by a console tag then digits in parenthesis and a space. - r':INFO:CONSOLE\(\d+\)\] ' - // Followed by the logged message in quotes. - r'"(?<consoleLog>.+)"' - // Followed by a comma and the source location. - r', source:.+$'); + final process = + await startProcess('Chrome', config.binary.toFilePath(), [ + '--no-first-run', + '--no-default-browser-check', + '--allow-file-access-from-files', + '--user-data-dir=${chromeDataDir.path}', + '--disable-default-apps', + '--disable-translate', + // These two flags are used to get the Chrome process to output messages + // to stderr so we can read the console.log messages. + // TODO(nshahan): Update if there is an easier way to get console.log + // messages. + '--enable-logging=stderr', + '--v=1', + bootstrapHtmlFile.path, + ]).then((process) { + StreamSubscription stdoutSubscription; + StreamSubscription stderrSubscription; + // The console.log messages in the output are prefixed with a header like: + // [42029:259:1126/154323.385793:INFO:CONSOLE(27547)] + final chromeConsoleLog = RegExp( + // Line starts with digits separated by ":", "." or "\"." + r'^\[[\d:\.\/]+' + // Followed by a console tag then digits in parenthesis and a space. + r':INFO:CONSOLE\(\d+\)\] ' + // Followed by the logged message in quotes. + r'"(?<consoleLog>.+)"' + // Followed by a comma and the source location. + r', source:.+$', + ); - var stdoutDone = Completer<void>(); - var stderrDone = Completer<void>(); + var stdoutDone = Completer<void>(); + var stderrDone = Completer<void>(); - void closeStdout([_]) { - if (!stdoutDone.isCompleted) stdoutDone.complete(); - } + void closeStdout([_]) { + if (!stdoutDone.isCompleted) stdoutDone.complete(); + } - void closeStderr([_]) { - if (!stderrDone.isCompleted) stderrDone.complete(); - } + void closeStderr([_]) { + if (!stderrDone.isCompleted) stderrDone.complete(); + } - stdoutSubscription = process.stdout - .listen((data) => outputSink.addStream, onDone: closeStderr); + stdoutSubscription = process.stdout.listen( + (data) => outputSink.addStream, + onDone: closeStderr, + ); - stderrSubscription = process.stderr - .transform(utf8.decoder) - .transform(LineSplitter()) - .listen((rawLine) { - final matches = chromeConsoleLog.allMatches(rawLine); - // Only considering lines that match the chrome console log format. - // All other output is discarded here because the logging is very - // chatty. - if (matches.isNotEmpty) { - final line = matches.single.namedGroup('consoleLog')!; - parseReloadReceipt( - test, line, reloadReceipts.add, outputSink.writeln); - } - }, onDone: closeStderr); + stderrSubscription = process.stderr + .transform(utf8.decoder) + .transform(LineSplitter()) + .listen((rawLine) { + final matches = chromeConsoleLog.allMatches(rawLine); + // Only considering lines that match the chrome console log format. + // All other output is discarded here because the logging is very + // chatty. + if (matches.isNotEmpty) { + final line = matches.single.namedGroup('consoleLog')!; + parseReloadReceipt( + test, + line, + reloadReceipts.add, + outputSink.writeln, + ); + } + }, onDone: closeStderr); - process.exitCode.then((exitCode) { - stdoutSubscription.cancel(); - stderrSubscription.cancel(); - closeStdout(); - closeStderr(); - }); + process.exitCode.then((exitCode) { + stdoutSubscription.cancel(); + stderrSubscription.cancel(); + closeStdout(); + closeStderr(); + }); - Future.wait([stdoutDone.future, stderrDone.future]).then((_) { - _debugPrint('Chrome process successfully shut down.', label: test.name); - }); + Future.wait([stdoutDone.future, stderrDone.future]).then((_) { + _debugPrint( + 'Chrome process successfully shut down.', + label: test.name, + ); + }); - return process; - }); + return process; + }); return await process.exitCode == 0 && reloadReceiptCheck(test, reloadReceipts); @@ -1246,8 +1476,9 @@ // Only allow Chrome when debugging a single test. // TODO(markzipan): Add support for full Chrome testing. if (options.runtime == RuntimePlatforms.chrome) { - var matchingTests = - Directory.fromUri(allTestsUri).listSync().where((testDir) { + var matchingTests = Directory.fromUri(allTestsUri).listSync().where(( + testDir, + ) { if (testDir is! Directory) return false; final testDirParts = testDir.uri.pathSegments; final testName = testDirParts[testDirParts.length - 2]; @@ -1255,8 +1486,10 @@ }); if (matchingTests.length > 1) { - throw Exception('Chrome is only supported when debugging a single test.' - "Please filter on a single test with '-f'."); + throw Exception( + 'Chrome is only supported when debugging a single test.' + "Please filter on a single test with '-f'.", + ); } } await super.runSuite(options); @@ -1265,52 +1498,62 @@ /// Hot reload test suite runner for behavior specific to the VM. class VMSuiteRunner extends HotReloadSuiteRunner { - final String vmPlatformDillFromSdkRoot = fe_shared.relativizeUri(sdkRoot, - buildRootUri.resolve('vm_platform_strong.dill'), fe_shared.isWindows); + final String vmPlatformDillFromSdkRoot = fe_shared.relativizeUri( + sdkRoot, + buildRootUri.resolve('vm_platform_strong.dill'), + fe_shared.isWindows, + ); VMSuiteRunner(super.options); @override List<String> get platformFrontEndServerArgs => [ - '--platform=$vmPlatformDillFromSdkRoot', - '--target=vm', - ]; + '--platform=$vmPlatformDillFromSdkRoot', + '--target=vm', + ]; @override Future<bool> compileGeneration( - HotReloadTest test, - int generation, - Directory outputDirectory, - List<String> updatedFiles, - HotReloadFrontendServerController controller) async { + HotReloadTest test, + int generation, + Directory outputDirectory, + List<String> updatedFiles, + HotReloadFrontendServerController controller, + ) async { // The first generation calls `compile`, but subsequent ones call // `recompile`. // Likewise, use the incremental output directory for `recompile` calls. // TODO(nshahan): Sending compile/recompile instructions is likely // the same across backends and should be shared code. String outputDillPath; - _print('Compiling generation $generation with the Frontend Server.', - label: test.name); + _print( + 'Compiling generation $generation with the Frontend Server.', + label: test.name, + ); CompilerOutput compilerOutput; if (generation == 0) { _debugPrint( - 'Compiling snapshot entrypoint: $snapshotEntrypointWithScheme', - label: test.name); + 'Compiling snapshot entrypoint: $snapshotEntrypointWithScheme', + label: test.name, + ); outputDillPath = outputDillUri.toFilePath(); - compilerOutput = - await controller.sendCompile(snapshotEntrypointWithScheme); + compilerOutput = await controller.sendCompile( + snapshotEntrypointWithScheme, + ); } else { _debugPrint( - 'Recompiling snapshot entrypoint: $snapshotEntrypointWithScheme', - label: test.name); + 'Recompiling snapshot entrypoint: $snapshotEntrypointWithScheme', + label: test.name, + ); outputDillPath = outputIncrementalDillUri.toFilePath(); // TODO(markzipan): Add logic to reject bad compiles. compilerOutput = await controller.sendRecompile( - snapshotEntrypointWithScheme, - invalidatedFiles: updatedFiles, - // The VM never uses the `recompile-restart` instruction as it does - // not recompile during a hot restart. - recompileRestart: false); + snapshotEntrypointWithScheme, + invalidatedFiles: updatedFiles, + // The VM never uses the `recompile-restart` instruction as it does + // not recompile during a hot restart. + recompileRestart: false, + ); } var hasExpectedCompileError = false; final expectedError = test.expectedErrors[generation]; @@ -1322,18 +1565,20 @@ compilerOutput.outputText.contains(expectedError)) { hasExpectedCompileError = true; _debugPrint( - 'VM rejected generation $generation: ' - '"${compilerOutput.outputText}"', - label: test.name); + 'VM rejected generation $generation: ' + '"${compilerOutput.outputText}"', + label: test.name, + ); // Remove the expected error from this test to avoid expecting it to // appear as a rejection at runtime. test.expectedErrors[generation] = HotReloadReceipt.compileTimeErrorMessage; } else { await reportTestOutcome( - test.name, - 'Test failed with compile error: ${compilerOutput.outputText}', - false); + test.name, + 'Test failed with compile error: ${compilerOutput.outputText}', + false, + ); return false; } } else if (test.expectedErrors.containsKey(generation)) { @@ -1343,17 +1588,21 @@ // accepted generation. The actual rejections will be validated when the // test runs on the VM. await controller.sendReject(); - _debugPrint('VM compile automatically rejected generation: $generation.', - label: test.name); + _debugPrint( + 'VM compile automatically rejected generation: $generation.', + label: test.name, + ); } else { controller.sendAccept(); } _debugPrint( - 'Frontend Server successfully compiled outputs to: ' - '$outputDillPath', - label: test.name); - final dillOutputDir = - Directory.fromUri(outputDirectory.uri.resolve('generation$generation')); + 'Frontend Server successfully compiled outputs to: ' + '$outputDillPath', + label: test.name, + ); + final dillOutputDir = Directory.fromUri( + outputDirectory.uri.resolve('generation$generation'), + ); dillOutputDir.createSync(); // Write an .error.dill file as a signal to the runtime utils that this // generation contains compile time errors and should not be reloaded. @@ -1362,17 +1611,23 @@ : dillOutputDir.uri.resolve('${test.name}.dill'); // Write dills to their respective generation. _print('Writing generation $generation assets.', label: test.name); - _debugPrint('Writing dill to ${dillOutputUri.toFilePath()}', - label: test.name); + _debugPrint( + 'Writing dill to ${dillOutputUri.toFilePath()}', + label: test.name, + ); File(outputDillPath).copySync(dillOutputUri.toFilePath()); return true; } @override Future<bool> runTest( - HotReloadTest test, Directory tempDirectory, IOSink outputSink) async { - final firstGenerationDillUri = - tempDirectory.uri.resolve('generation0/${test.name}.dill'); + HotReloadTest test, + Directory tempDirectory, + IOSink outputSink, + ) async { + final firstGenerationDillUri = tempDirectory.uri.resolve( + 'generation0/${test.name}.dill', + ); // Start the VM at generation 0. final vmArgs = [ '--enable-vm-service=0', // 0 avoids port collisions. @@ -1381,40 +1636,39 @@ firstGenerationDillUri.toFilePath(), ]; _debugPrint( - 'Starting VM with command: ' - '${Platform.executable} ${vmArgs.join(" ")}', - label: test.name); + 'Starting VM with command: ' + '${Platform.executable} ${vmArgs.join(" ")}', + label: test.name, + ); final reloadReceipts = <HotReloadReceipt>[]; final vm = await Process.start(Platform.executable, vmArgs); vm.stdout .transform(utf8.decoder) .transform(LineSplitter()) - .listen((line) => parseReloadReceipt( - test, - line, - reloadReceipts.add, - (line) { - _debugPrint('VM stdout: $line', label: test.name); - outputSink.writeln(line); - }, - )); - vm.stderr - .transform(utf8.decoder) - .transform(LineSplitter()) - .listen((String err) { + .listen( + (line) => parseReloadReceipt(test, line, reloadReceipts.add, (line) { + _debugPrint('VM stdout: $line', label: test.name); + outputSink.writeln(line); + }), + ); + vm.stderr.transform(utf8.decoder).transform(LineSplitter()).listen(( + String err, + ) { _debugPrint('VM stderr: $err', label: test.name); outputSink.writeln(err); }); _print('Executing VM test.', label: test.name); final testTimeoutSeconds = 10; - final vmExitCode = await vm.exitCode - .timeout(Duration(seconds: testTimeoutSeconds), onTimeout: () { - final timeoutText = 'Test timed out after $testTimeoutSeconds seconds.'; - _print(timeoutText, label: test.name); - outputSink.writeln(timeoutText); - vm.kill(); - return 1; - }); + final vmExitCode = await vm.exitCode.timeout( + Duration(seconds: testTimeoutSeconds), + onTimeout: () { + final timeoutText = 'Test timed out after $testTimeoutSeconds seconds.'; + _print(timeoutText, label: test.name); + outputSink.writeln(timeoutText); + vm.kill(); + return 1; + }, + ); return vmExitCode == 0 && reloadReceiptCheck(test, reloadReceipts); } }
diff --git a/pkg/dev_compiler/test/id_testing_helper.dart b/pkg/dev_compiler/test/id_testing_helper.dart index 930d410..ba9240b 100644 --- a/pkg/dev_compiler/test/id_testing_helper.dart +++ b/pkg/dev_compiler/test/id_testing_helper.dart
@@ -41,76 +41,98 @@ } /// Base class for computing id-test data from a DDC compilation. -abstract class DdcDataComputer<T> extends DataComputer<T, TestConfig, - MemoryCompilerResult, DdcTestResultData> { +abstract class DdcDataComputer<T> + extends + DataComputer<T, TestConfig, MemoryCompilerResult, DdcTestResultData> { const DdcDataComputer(); } /// Creates a test runner for [dataComputer] on [testedConfigs]. RunTestFunction<T> runTestFor<T>( - DdcDataComputer<T> dataComputer, List<DdcTestConfig> testedConfigs) { - return (MarkerOptions markerOptions, TestData testData, - {required bool testAfterFailures, - required bool verbose, - required bool succinct, - required bool printCode, - Map<String, List<String>>? skipMap, - required Uri nullUri}) { - return runTest(markerOptions, testData, dataComputer, testedConfigs, - testAfterFailures: testAfterFailures, - verbose: verbose, - succinct: succinct, - printCode: printCode, - onFailure: onFailure, - skipMap: skipMap, - nullUri: nullUri); + DdcDataComputer<T> dataComputer, + List<DdcTestConfig> testedConfigs, +) { + return ( + MarkerOptions markerOptions, + TestData testData, { + required bool testAfterFailures, + required bool verbose, + required bool succinct, + required bool printCode, + Map<String, List<String>>? skipMap, + required Uri nullUri, + }) { + return runTest( + markerOptions, + testData, + dataComputer, + testedConfigs, + testAfterFailures: testAfterFailures, + verbose: verbose, + succinct: succinct, + printCode: printCode, + onFailure: onFailure, + skipMap: skipMap, + nullUri: nullUri, + ); }; } /// Runs [dataComputer] on [testData] for each [testedConfigs]. Future<Map<String, TestResult<T>>> runTest<T>( - MarkerOptions markerOptions, - TestData testData, - DdcDataComputer<T> dataComputer, - List<DdcTestConfig> testedConfigs, - {required bool testAfterFailures, - required bool verbose, - required bool succinct, - required bool printCode, - bool forUserLibrariesOnly = true, - Iterable<Id> globalIds = const <Id>[], - required void Function(String message) onFailure, - Map<String, List<String>>? skipMap, - required Uri nullUri}) async { + MarkerOptions markerOptions, + TestData testData, + DdcDataComputer<T> dataComputer, + List<DdcTestConfig> testedConfigs, { + required bool testAfterFailures, + required bool verbose, + required bool succinct, + required bool printCode, + bool forUserLibrariesOnly = true, + Iterable<Id> globalIds = const <Id>[], + required void Function(String message) onFailure, + Map<String, List<String>>? skipMap, + required Uri nullUri, +}) async { var results = <String, TestResult<T>>{}; for (var config in testedConfigs) { results[config.marker] = await runTestForConfig( - markerOptions, testData, dataComputer, config, - fatalErrors: !testAfterFailures, - onFailure: onFailure, - verbose: verbose, - succinct: succinct, - printCode: printCode, - nullUri: nullUri); + markerOptions, + testData, + dataComputer, + config, + fatalErrors: !testAfterFailures, + onFailure: onFailure, + verbose: verbose, + succinct: succinct, + printCode: printCode, + nullUri: nullUri, + ); } return results; } /// Computes the [TestResult] for running [dataComputer] on [testData] for /// the given test [config]. -Future<TestResult<T>> runTestForConfig<T>(MarkerOptions markerOptions, - TestData testData, DdcDataComputer<T> dataComputer, DdcTestConfig config, - {required bool fatalErrors, - required bool verbose, - required bool succinct, - required bool printCode, - bool forUserLibrariesOnly = true, - Iterable<Id> globalIds = const <Id>[], - required void Function(String message) onFailure, - required Uri nullUri}) async { +Future<TestResult<T>> runTestForConfig<T>( + MarkerOptions markerOptions, + TestData testData, + DdcDataComputer<T> dataComputer, + DdcTestConfig config, { + required bool fatalErrors, + required bool verbose, + required bool succinct, + required bool printCode, + bool forUserLibrariesOnly = true, + Iterable<Id> globalIds = const <Id>[], + required void Function(String message) onFailure, + required Uri nullUri, +}) async { var result = await compileFromMemory( - testData.memorySourceFiles, testData.entryPoint, - explicitExperimentalFlags: config.experimentalFlags); + testData.memorySourceFiles, + testData.entryPoint, + explicitExperimentalFlags: config.experimentalFlags, + ); var errors = <FormattedMessage>[]; for (var error in result.errors) { @@ -120,12 +142,17 @@ } var testResultData = DdcTestResultData(config, result); return processCompiledResult( - markerOptions, testData, dataComputer, testResultData, errors, - fatalErrors: fatalErrors, - verbose: verbose, - succinct: succinct, - onFailure: onFailure, - nullUri: nullUri); + markerOptions, + testData, + dataComputer, + testResultData, + errors, + fatalErrors: fatalErrors, + verbose: verbose, + succinct: succinct, + onFailure: onFailure, + nullUri: nullUri, + ); } /// Base class for extracting AST-based test data from a DDC compilation. @@ -142,6 +169,10 @@ @override void report(Uri uri, int offset, String message) { printMessageInLocation( - compilerResult.ddcResult.component.uriToSource, uri, offset, message); + compilerResult.ddcResult.component.uriToSource, + uri, + offset, + message, + ); } }
diff --git a/pkg/dev_compiler/test/js/builder_test.dart b/pkg/dev_compiler/test/js/builder_test.dart index 9a1ac18..30e5c96 100644 --- a/pkg/dev_compiler/test/js/builder_test.dart +++ b/pkg/dev_compiler/test/js/builder_test.dart
@@ -18,20 +18,22 @@ group('MiniJsParser', () { // TODO(ochafik): Add more coverage. test('parses classes with complex members', () { - _checkExpression('class Foo {\n' - ' [foo](...args) {}\n' - ' [#0](x) {}\n' - ' static [foo](...args) {}\n' - ' static [#1](x) {}\n' - ' get [foo]() {}\n' - ' get [#2]() {}\n' - ' static get [foo]() {}\n' - ' static get [#3]() {}\n' - ' set [foo](v) {}\n' - ' set [#4](v) {}\n' - ' static set [foo](v) {}\n' - ' static set [#5](v) {}\n' - '}'); + _checkExpression( + 'class Foo {\n' + ' [foo](...args) {}\n' + ' [#0](x) {}\n' + ' static [foo](...args) {}\n' + ' static [#1](x) {}\n' + ' get [foo]() {}\n' + ' get [#2]() {}\n' + ' static get [foo]() {}\n' + ' static get [#3]() {}\n' + ' set [foo](v) {}\n' + ' set [#4](v) {}\n' + ' static set [foo](v) {}\n' + ' static set [#5](v) {}\n' + '}', + ); }); test('parses statements', () { _checkStatement('for (let i = 0; i < 10; i++) {\n}\n');
diff --git a/pkg/dev_compiler/test/memory_compiler.dart b/pkg/dev_compiler/test/memory_compiler.dart index 5f96e69..14d36a5 100644 --- a/pkg/dev_compiler/test/memory_compiler.dart +++ b/pkg/dev_compiler/test/memory_compiler.dart
@@ -19,7 +19,11 @@ final List<fe.DiagnosticMessage> errors; MemoryCompilerResult( - this.ddcResult, this.compiler, this.program, this.errors); + this.ddcResult, + this.compiler, + this.program, + this.errors, + ); } /// Result of compiling using [componentFromMemory]. @@ -45,9 +49,11 @@ /// be absolute, using [baseUri] (defaulted to [memoryDirectory]) to refer to a /// file from [memoryFiles]. Future<MemoryComponentResult> componentFromMemory( - Map<String, String> memoryFiles, Uri entryPoint, - {Map<fe.ExperimentalFlag, bool> explicitExperimentalFlags = const {}, - Uri? baseUri}) async { + Map<String, String> memoryFiles, + Uri entryPoint, { + Map<fe.ExperimentalFlag, bool> explicitExperimentalFlags = const {}, + Uri? baseUri, +}) async { baseUri ??= memoryDirectory; var errors = <fe.DiagnosticMessage>[]; void diagnosticMessageHandler(fe.DiagnosticMessage message) { @@ -64,19 +70,21 @@ .writeAsStringSync(entry.value); } var compilerState = fe.initializeCompiler( - null, - false, - sourcePathToUri(getSdkPath()), - sourcePathToUri(defaultSdkSummaryPath), - null, - sourcePathToUri(defaultLibrarySpecPath), - [], - DevCompilerTarget(TargetFlags(trackWidgetCreation: false)), - fileSystem: fe.HybridFileSystem(memoryFileSystem), - environmentDefines: {}, - explicitExperimentalFlags: explicitExperimentalFlags); - var result = - await fe.compile(compilerState, [entryPoint], diagnosticMessageHandler); + null, + false, + sourcePathToUri(getSdkPath()), + sourcePathToUri(defaultSdkSummaryPath), + null, + sourcePathToUri(defaultLibrarySpecPath), + [], + DevCompilerTarget(TargetFlags(trackWidgetCreation: false)), + fileSystem: fe.HybridFileSystem(memoryFileSystem), + environmentDefines: {}, + explicitExperimentalFlags: explicitExperimentalFlags, + ); + var result = await fe.compile(compilerState, [ + entryPoint, + ], diagnosticMessageHandler); if (result == null) { throw 'Memory compilation failed'; } @@ -90,11 +98,13 @@ /// be absolute, using [baseUri] (defaulted to [memoryDirectory]) to refer to a /// file from [memoryFiles]. Future<MemoryComponentResult> incrementalComponentFromMemory( - Map<String, String> memoryFiles, Uri entryPoint, - {Map<fe.ExperimentalFlag, bool> explicitExperimentalFlags = const {}, - Uri? baseUri, - fe.InitializedCompilerState? initialCompilerState, - Uri? packageConfigUri}) async { + Map<String, String> memoryFiles, + Uri entryPoint, { + Map<fe.ExperimentalFlag, bool> explicitExperimentalFlags = const {}, + Uri? baseUri, + fe.InitializedCompilerState? initialCompilerState, + Uri? packageConfigUri, +}) async { baseUri ??= memoryDirectory; var errors = <fe.DiagnosticMessage>[]; void diagnosticMessageHandler(fe.DiagnosticMessage message) { @@ -111,35 +121,39 @@ .writeAsStringSync(entry.value); } var inputDigests = { - sourcePathToUri(defaultSdkSummaryPath): const [0] + sourcePathToUri(defaultSdkSummaryPath): const [0], }; var compilerState = await fe.initializeIncrementalCompiler( - initialCompilerState, - {}, - [], - false, - sourcePathToUri(getSdkPath()), - sourcePathToUri(defaultSdkSummaryPath), - packageConfigUri, - sourcePathToUri(defaultLibrarySpecPath), - [], - inputDigests, - DevCompilerTarget(TargetFlags(trackWidgetCreation: false)), - fileSystem: fe.HybridFileSystem(memoryFileSystem), - environmentDefines: {}, - explicitExperimentalFlags: explicitExperimentalFlags); + initialCompilerState, + {}, + [], + false, + sourcePathToUri(getSdkPath()), + sourcePathToUri(defaultSdkSummaryPath), + packageConfigUri, + sourcePathToUri(defaultLibrarySpecPath), + [], + inputDigests, + DevCompilerTarget(TargetFlags(trackWidgetCreation: false)), + fileSystem: fe.HybridFileSystem(memoryFileSystem), + environmentDefines: {}, + explicitExperimentalFlags: explicitExperimentalFlags, + ); var incrementalCompiler = compilerState.incrementalCompiler!; compilerState.options.onDiagnostic = diagnosticMessageHandler; - var incrementalCompilerResult = await incrementalCompiler - .computeDelta(entryPoints: [entryPoint], fullComponent: false); + var incrementalCompilerResult = await incrementalCompiler.computeDelta( + entryPoints: [entryPoint], + fullComponent: false, + ); var cachedSdkInput = compilerState.workerInputCache![sourcePathToUri(defaultSdkSummaryPath)]; var result = fe.DdcResult( - incrementalCompilerResult.component, - cachedSdkInput?.component, - [], - incrementalCompilerResult.classHierarchy, - incrementalCompilerResult.neededDillLibraries); + incrementalCompilerResult.component, + cachedSdkInput?.component, + [], + incrementalCompilerResult.classHierarchy, + incrementalCompilerResult.neededDillLibraries, + ); return MemoryComponentResult(result, errors, compilerState); } @@ -149,9 +163,11 @@ /// be absolute, using [memoryDirectory] as a base uri to refer to a file from /// [memoryFiles]. Future<MemoryCompilerResult> compileFromMemory( - Map<String, String> memoryFiles, Uri entryPoint, - {Map<fe.ExperimentalFlag, bool>? explicitExperimentalFlags, - Uri? baseUri}) async { + Map<String, String> memoryFiles, + Uri entryPoint, { + Map<fe.ExperimentalFlag, bool>? explicitExperimentalFlags, + Uri? baseUri, +}) async { baseUri ??= memoryDirectory; var MemoryComponentResult(ddcResult: result, :errors) = await componentFromMemory(memoryFiles, entryPoint, baseUri: baseUri);
diff --git a/pkg/dev_compiler/test/modular_helpers.dart b/pkg/dev_compiler/test/modular_helpers.dart index f984112..3b3ea73 100644 --- a/pkg/dev_compiler/test/modular_helpers.dart +++ b/pkg/dev_compiler/test/modular_helpers.dart
@@ -48,8 +48,12 @@ bool get notOnSdk => false; @override - Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri, - List<String> flags) async { + Future<void> execute( + Module module, + Uri root, + ModuleDataToRelativeUri toUri, + List<String> flags, + ) async { if (_options.verbose) print('\nstep: source-to-dill on $module'); // We use non file-URI schemes for representing source locations in a @@ -71,21 +75,19 @@ List<String> extraArgs; if (module.isSdk) { sources = ['dart:core']; - extraArgs = [ - '--libraries-file', - '$rootScheme:///sdk/lib/libraries.json', - ]; + extraArgs = ['--libraries-file', '$rootScheme:///sdk/lib/libraries.json']; assert(transitiveDependencies.isEmpty); } else { sources = module.sources.map(sourceToImportUri).toList(); extraArgs = [ '--packages-file', - '$rootScheme:/.dart_tool/package_config.json' + '$rootScheme:/.dart_tool/package_config.json', ]; } - var sdkModule = - module.isSdk ? module : module.dependencies.firstWhere((m) => m.isSdk); + var sdkModule = module.isSdk + ? module + : module.dependencies.firstWhere((m) => m.isSdk); var args = [ _kernelWorkerScript, @@ -112,7 +114,11 @@ ]; var result = await runProcess( - _dartExecutable, args, root.toFilePath(), _options.verbose); + _dartExecutable, + args, + root.toFilePath(), + _options.verbose, + ); checkExitCode(result, this, module, _options.verbose); } @@ -149,8 +155,12 @@ bool get notOnSdk => false; @override - Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri, - List<String> flags) async { + Future<void> execute( + Module module, + Uri root, + ModuleDataToRelativeUri toUri, + List<String> flags, + ) async { if (_options.verbose) print('\nstep: ddc on $module'); var transitiveDependencies = computeTransitiveDependencies(module); @@ -170,8 +180,10 @@ } else { var sdkModule = module.dependencies.firstWhere((m) => m.isSdk); sources = module.sources - .map((relativeUri) => - _sourceToImportUri(module, rootScheme, relativeUri)) + .map( + (relativeUri) => + _sourceToImportUri(module, rootScheme, relativeUri), + ) .toList(); extraArgs = [ '--dart-sdk-summary', @@ -202,7 +214,11 @@ '$output', ]; var result = await runProcess( - _dartExecutable, args, root.toFilePath(), _options.verbose); + _dartExecutable, + args, + root.toFilePath(), + _options.verbose, + ); checkExitCode(result, this, module, _options.verbose); } @@ -235,8 +251,12 @@ bool get notOnSdk => false; @override - Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri, - List<String> flags) async { + Future<void> execute( + Module module, + Uri root, + ModuleDataToRelativeUri toUri, + List<String> flags, + ) async { if (_options.verbose) print('\nstep: d8 on $module'); // Rename sdk.js to dart_sdk.js (the alternative, but more hermetic solution @@ -246,8 +266,9 @@ throw 'error: dart_sdk.js already exists.'; } - await File.fromUri(root.resolve('sdk.js')) - .copy(root.resolve('dart_sdk.js').toFilePath()); + await File.fromUri( + root.resolve('sdk.js'), + ).copy(root.resolve('dart_sdk.js').toFilePath()); var runjs = ''' import { dart, _isolate_helper } from 'dart_sdk.js'; import { main } from 'main.js'; @@ -259,13 +280,18 @@ '${root.resolveUri(toUri(module, jsId)).toFilePath()}.wrapper.js'; await File(wrapper).writeAsString(runjs); var d8Args = ['--module', wrapper]; - var result = await runProcess(sdkRoot.resolve(_d8executable).toFilePath(), - d8Args, root.toFilePath(), _options.verbose); + var result = await runProcess( + sdkRoot.resolve(_d8executable).toFilePath(), + d8Args, + root.toFilePath(), + _options.verbose, + ); checkExitCode(result, this, module, _options.verbose); - await File.fromUri(root.resolveUri(toUri(module, txtId))) - .writeAsString(result.stdout as String); + await File.fromUri( + root.resolveUri(toUri(module, txtId)), + ).writeAsString(result.stdout as String); } @override @@ -301,12 +327,14 @@ Future<void> resolveScripts(Options options) async { _options = options; Future<String> resolve( - String sdkSourcePath, String relativeSnapshotPath) async { + String sdkSourcePath, + String relativeSnapshotPath, + ) async { var result = sdkRoot.resolve(sdkSourcePath).toFilePath(); if (_options.useSdk) { - var snapshot = Uri.file(Platform.resolvedExecutable) - .resolve(relativeSnapshotPath) - .toFilePath(); + var snapshot = Uri.file( + Platform.resolvedExecutable, + ).resolve(relativeSnapshotPath).toFilePath(); if (await File(snapshot).exists()) { return snapshot; } @@ -314,11 +342,15 @@ return result; } - _dartdevcScript = await resolve('pkg/dev_compiler/bin/dartdevc.dart', - 'snapshots/dartdevc_aot.dart.snapshot'); + _dartdevcScript = await resolve( + 'pkg/dev_compiler/bin/dartdevc.dart', + 'snapshots/dartdevc_aot.dart.snapshot', + ); if (File(_dartdevcScript).existsSync()) { - _kernelWorkerScript = await resolve('utils/bazel/kernel_worker.dart', - 'snapshots/kernel_worker_aot.dart.snapshot'); + _kernelWorkerScript = await resolve( + 'utils/bazel/kernel_worker.dart', + 'snapshots/kernel_worker_aot.dart.snapshot', + ); var sdkPath = p.dirname(p.dirname(Platform.resolvedExecutable)); _dartExecutable = p.absolute( sdkPath,
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart index 792cd6b..3bef243 100644 --- a/pkg/dev_compiler/test/modular_suite.dart +++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -16,12 +16,13 @@ final options = Options.parse(args); await resolveScripts(options); await runSuite( - sdkRoot.resolve('tests/modular/'), - 'tests/modular', - options, - IOPipeline([ - SourceToSummaryDillStep(), - DDCStep(canaryFeatures: false), - RunD8(), - ], cacheSharedModules: true)); + sdkRoot.resolve('tests/modular/'), + 'tests/modular', + options, + IOPipeline([ + SourceToSummaryDillStep(), + DDCStep(canaryFeatures: false), + RunD8(), + ], cacheSharedModules: true), + ); }
diff --git a/pkg/dev_compiler/test/modular_suite_canary.dart b/pkg/dev_compiler/test/modular_suite_canary.dart index cdd1fae..e91fd92e 100644 --- a/pkg/dev_compiler/test/modular_suite_canary.dart +++ b/pkg/dev_compiler/test/modular_suite_canary.dart
@@ -16,12 +16,13 @@ final options = Options.parse(args); await resolveScripts(options); await runSuite( - sdkRoot.resolve('tests/modular/'), - 'tests/modular', - options, - IOPipeline([ - SourceToSummaryDillStep(), - DDCStep(canaryFeatures: true), - RunD8(), - ], cacheSharedModules: true)); + sdkRoot.resolve('tests/modular/'), + 'tests/modular', + options, + IOPipeline([ + SourceToSummaryDillStep(), + DDCStep(canaryFeatures: true), + RunD8(), + ], cacheSharedModules: true), + ); }
diff --git a/pkg/dev_compiler/test/module_metadata_test.dart b/pkg/dev_compiler/test/module_metadata_test.dart index da60be7..17deda4 100644 --- a/pkg/dev_compiler/test/module_metadata_test.dart +++ b/pkg/dev_compiler/test/module_metadata_test.dart
@@ -37,18 +37,19 @@ // Read metadata. var moduleJson = json.decode(utf8.decode(file.readAsBytesSync())); - var newModule = - ModuleMetadata.fromJson(moduleJson as Map<String, dynamic>); + var newModule = ModuleMetadata.fromJson( + moduleJson as Map<String, dynamic>, + ); testMetadataFields(newModule, version); }); test('read later backward-compatible patch version', () async { // Create metadata with next patch version. var version = ModuleMetadataVersion( - ModuleMetadataVersion.current.majorVersion, - ModuleMetadataVersion.current.minorVersion, - ModuleMetadataVersion.current.patchVersion + 1) - .version; + ModuleMetadataVersion.current.majorVersion, + ModuleMetadataVersion.current.minorVersion, + ModuleMetadataVersion.current.patchVersion + 1, + ).version; var module = createMetadata(version); @@ -58,18 +59,19 @@ // Read metadata. var moduleJson = json.decode(utf8.decode(file.readAsBytesSync())); - var newModule = - ModuleMetadata.fromJson(moduleJson as Map<String, dynamic>); + var newModule = ModuleMetadata.fromJson( + moduleJson as Map<String, dynamic>, + ); testMetadataFields(newModule, version); }); test('read later backward-compatible minor version', () async { // Create metadata with next minor version. var version = ModuleMetadataVersion( - ModuleMetadataVersion.current.majorVersion, - ModuleMetadataVersion.current.minorVersion + 1, - ModuleMetadataVersion.current.patchVersion + 1) - .version; + ModuleMetadataVersion.current.majorVersion, + ModuleMetadataVersion.current.minorVersion + 1, + ModuleMetadataVersion.current.patchVersion + 1, + ).version; var module = createMetadata(version); // Write metadata. @@ -78,18 +80,19 @@ // Read metadata. var moduleJson = json.decode(utf8.decode(file.readAsBytesSync())); - var newModule = - ModuleMetadata.fromJson(moduleJson as Map<String, dynamic>); + var newModule = ModuleMetadata.fromJson( + moduleJson as Map<String, dynamic>, + ); testMetadataFields(newModule, version); }); test('fail to read later non-backward-compatible major version', () async { // Create metadata with next minor version. var version = ModuleMetadataVersion( - ModuleMetadataVersion.current.majorVersion + 1, - ModuleMetadataVersion.current.minorVersion + 1, - ModuleMetadataVersion.current.patchVersion + 1) - .version; + ModuleMetadataVersion.current.majorVersion + 1, + ModuleMetadataVersion.current.minorVersion + 1, + ModuleMetadataVersion.current.patchVersion + 1, + ).version; var module = createMetadata(version); // Write metadata. @@ -103,7 +106,9 @@ newModule = ModuleMetadata.fromJson(moduleJson as Map<String, dynamic>); } catch (e) { expect( - e.toString(), 'Exception: Unsupported metadata version $version'); + e.toString(), + 'Exception: Unsupported metadata version $version', + ); } expect(newModule, null); @@ -111,11 +116,22 @@ }); } -ModuleMetadata createMetadata(String version) => ModuleMetadata( - 'module', 'closure', 'module.map', 'module.js', 'module.full.dill', - version: version) - ..addLibrary(LibraryMetadata('library', 'package:library/test.dart', - 'file:///source/library/lib/test.dart', ['src/test2.dart'])); +ModuleMetadata createMetadata(String version) => + ModuleMetadata( + 'module', + 'closure', + 'module.map', + 'module.js', + 'module.full.dill', + version: version, + )..addLibrary( + LibraryMetadata( + 'library', + 'package:library/test.dart', + 'file:///source/library/lib/test.dart', + ['src/test2.dart'], + ), + ); void testMetadataFields(ModuleMetadata module, String version) { // Reader always creates current metadata version.
diff --git a/pkg/dev_compiler/test/module_symbols/function_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/function_symbols_test.dart index 68598e8..d5db374 100644 --- a/pkg/dev_compiler/test/module_symbols/function_symbols_test.dart +++ b/pkg/dev_compiler/test/module_symbols/function_symbols_test.dart
@@ -56,8 +56,10 @@ expect(functionSymbol.location!.scriptId, endsWith('/foo.dart')); }); test('has start token', () async { - expect(functionSymbol.location!.tokenPos, - source.indexOf('topLevelFunction')); + expect( + functionSymbol.location!.tokenPos, + source.indexOf('topLevelFunction'), + ); }); test('has end token', () async { expect(functionSymbol.location!.endTokenPos, source.lastIndexOf('}')); @@ -229,12 +231,15 @@ setUpAll(() async { driver = TestDriver(options, source); var symbols = await driver.compileAndGetSymbols(); - functionWithPositionalArgSymbol = symbols.functions - .singleWhere((f) => f.name == 'functionWithPositionalArg'); - functionWithOptionalArgSymbol = symbols.functions - .singleWhere((f) => f.name == 'functionWithOptionalArg'); - functionWithNamedArgSymbol = symbols.functions - .singleWhere((f) => f.name == 'functionWithNamedArg'); + functionWithPositionalArgSymbol = symbols.functions.singleWhere( + (f) => f.name == 'functionWithPositionalArg', + ); + functionWithOptionalArgSymbol = symbols.functions.singleWhere( + (f) => f.name == 'functionWithOptionalArg', + ); + functionWithNamedArgSymbol = symbols.functions.singleWhere( + (f) => f.name == 'functionWithNamedArg', + ); xSymbol = symbols.variables.singleWhere((v) => v.name == 'x'); ySymbol = symbols.variables.singleWhere((v) => v.name == 'y'); zSymbol = symbols.variables.singleWhere((v) => v.name == 'z');
diff --git a/pkg/dev_compiler/test/module_symbols/module_symbols_json_test.dart b/pkg/dev_compiler/test/module_symbols/module_symbols_json_test.dart index ad23ffd..48c2e75 100644 --- a/pkg/dev_compiler/test/module_symbols/module_symbols_json_test.dart +++ b/pkg/dev_compiler/test/module_symbols/module_symbols_json_test.dart
@@ -25,17 +25,22 @@ void main() { var intType = ClassSymbol( - name: 'int', - localId: 'int', - scopeId: 'dart:core', - location: SourceLocation( - scriptId: 'sdkIdForTest', tokenPos: 42, endTokenPos: 42)); + name: 'int', + localId: 'int', + scopeId: 'dart:core', + location: SourceLocation( + scriptId: 'sdkIdForTest', + tokenPos: 42, + endTokenPos: 42, + ), + ); var libraryId = 'lib1'; var main = Script( - uri: 'package:example/hello_world.dart', - localId: '1', - libraryId: libraryId); + uri: 'package:example/hello_world.dart', + localId: '1', + libraryId: libraryId, + ); var myClassId = 'MyClass<T>'; var fooId = 'foo'; var scopeId = '1'; @@ -246,16 +251,20 @@ test('Read supported version', () { var version = SemanticVersion(0, 2, 3).version; - var json = ModuleSymbols(version: version, moduleName: 'moduleNameForTest') - .toJson(); + var json = ModuleSymbols( + version: version, + moduleName: 'moduleNameForTest', + ).toJson(); expect(ModuleSymbols.fromJson(json).version, equals(version)); }); test('Read unsupported version', () { var version = SemanticVersion(1, 2, 3).version; - var json = ModuleSymbols(version: version, moduleName: 'moduleNameForTest') - .toJson(); + var json = ModuleSymbols( + version: version, + moduleName: 'moduleNameForTest', + ).toJson(); expect(() => ModuleSymbols.fromJson(json), throwsException); }); @@ -268,15 +277,16 @@ .having((loc) => loc.endTokenPos, 'endTokenPos', other.endTokenPos); TypeMatcher<LibrarySymbolDependency> matchesDependency( - LibrarySymbolDependency other) => - isA<LibrarySymbolDependency>() - .having((dep) => dep.isDeferred, 'isDeferred', other.isDeferred) - .having((dep) => dep.isImport, 'isImport', other.isImport) - .having((dep) => dep.prefix, 'prefix', other.prefix) - .having((dep) => dep.targetId, 'targetId', other.targetId); + LibrarySymbolDependency other, +) => isA<LibrarySymbolDependency>() + .having((dep) => dep.isDeferred, 'isDeferred', other.isDeferred) + .having((dep) => dep.isImport, 'isImport', other.isImport) + .having((dep) => dep.prefix, 'prefix', other.prefix) + .having((dep) => dep.targetId, 'targetId', other.targetId); -Iterable<Matcher> matchDependencies(List<LibrarySymbolDependency> list) => - [for (var e in list) matchesDependency(e)]; +Iterable<Matcher> matchDependencies(List<LibrarySymbolDependency> list) => [ + for (var e in list) matchesDependency(e), +]; TypeMatcher<LibrarySymbol> matchesLibrary(LibrarySymbol other) => isA<LibrarySymbol>() @@ -288,8 +298,11 @@ .having((lib) => lib.scopeIds, 'scopeIds', other.scopeIds) .having((lib) => lib.variableIds, 'variableIds', other.variableIds) .having((lib) => lib.location, 'location', isNull) - .having((lib) => lib.dependencies, 'dependencies', - matchDependencies(other.dependencies)); + .having( + (lib) => lib.dependencies, + 'dependencies', + matchDependencies(other.dependencies), + ); TypeMatcher<ClassSymbol> matchesClass(ClassSymbol other) => isA<ClassSymbol>() .having((cls) => cls.name, 'name', other.name) @@ -306,7 +319,10 @@ .having((cls) => cls.scopeIds, 'scopeIds', other.scopeIds) .having((cls) => cls.variableIds, 'variableIds', other.variableIds) .having( - (cls) => cls.location, 'location', matchesLocation(other.location!)); + (cls) => cls.location, + 'location', + matchesLocation(other.location!), + ); TypeMatcher<FunctionTypeSymbol> matchesFunctionType(FunctionTypeSymbol other) => isA<FunctionTypeSymbol>() @@ -314,15 +330,30 @@ .having((fun) => fun.localId, 'localId', other.localId) .having((fun) => fun.scopeId, 'scopeId', other.scopeId) .having( - (fun) => fun.typeParameters, 'typeParameters', other.typeParameters) - .having((fun) => fun.parameterTypeIds, 'parameterTypeIds', - other.parameterTypeIds) - .having((fun) => fun.optionalParameterTypeIds, - 'optionalParameterTypeIds', other.optionalParameterTypeIds) - .having((fun) => fun.namedParameterTypeIds, 'namedParameterTypeIds', - other.namedParameterTypeIds) - .having((fun) => fun.location, 'location', - matchesLocation(other.location!)); + (fun) => fun.typeParameters, + 'typeParameters', + other.typeParameters, + ) + .having( + (fun) => fun.parameterTypeIds, + 'parameterTypeIds', + other.parameterTypeIds, + ) + .having( + (fun) => fun.optionalParameterTypeIds, + 'optionalParameterTypeIds', + other.optionalParameterTypeIds, + ) + .having( + (fun) => fun.namedParameterTypeIds, + 'namedParameterTypeIds', + other.namedParameterTypeIds, + ) + .having( + (fun) => fun.location, + 'location', + matchesLocation(other.location!), + ); TypeMatcher<FunctionSymbol> matchesFunction(FunctionSymbol other) => isA<FunctionSymbol>() @@ -335,8 +366,11 @@ .having((fun) => fun.typeId, 'typeId', other.typeId) .having((fun) => fun.scopeIds, 'scopeIds', other.scopeIds) .having((fun) => fun.variableIds, 'variableIds', other.variableIds) - .having((fun) => fun.location, 'location', - matchesLocation(other.location!)); + .having( + (fun) => fun.location, + 'location', + matchesLocation(other.location!), + ); TypeMatcher<ScopeSymbol> matchesScope(ScopeSymbol other) => isA<ScopeSymbol>() .having((scope) => scope.localId, 'localId', other.localId) @@ -344,8 +378,11 @@ .having((scope) => scope.id, 'id', other.id) .having((scope) => scope.scopeIds, 'scopeIds', other.scopeIds) .having((scope) => scope.variableIds, 'variableIds', other.variableIds) - .having((scope) => scope.location, 'location', - matchesLocation(other.location!)); + .having( + (scope) => scope.location, + 'location', + matchesLocation(other.location!), + ); TypeMatcher<VariableSymbol> matchesVariable(VariableSymbol other) => isA<VariableSymbol>() @@ -356,8 +393,11 @@ .having((variable) => variable.isConst, 'isConst', other.isConst) .having((variable) => variable.isStatic, 'isStatic', other.isStatic) .having((variable) => variable.isFinal, 'isFinal', other.isFinal) - .having((variable) => variable.location, 'location', - matchesLocation(other.location!)); + .having( + (variable) => variable.location, + 'location', + matchesLocation(other.location!), + ); TypeMatcher<Script> matchesScript(Script other) => isA<Script>() .having((script) => script.uri, 'uri', other.uri)
diff --git a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart index 6dfb9ab..f115063 100644 --- a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart +++ b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
@@ -35,10 +35,11 @@ var moduleName = 'foo.dart'; var classHierarchy = compilerResult.classHierarchy; var compilerOptions = Options( - replCompile: true, - moduleName: moduleName, - moduleFormats: [setup.moduleFormat], - emitDebugSymbols: true); + replCompile: true, + moduleName: moduleName, + moduleFormats: [setup.moduleFormat], + emitDebugSymbols: true, + ); var coreTypes = compilerResult.coreTypes; final importToSummary = Map<Library, Component>.identity(); @@ -49,16 +50,24 @@ summaryToModule[component] = moduleName; // Compile Kernel AST to JS AST. - var kernel2jsCompiler = ProgramCompiler(component, classHierarchy, - compilerOptions, importToSummary, summaryToModule, - coreTypes: coreTypes); + var kernel2jsCompiler = ProgramCompiler( + component, + classHierarchy, + compilerOptions, + importToSummary, + summaryToModule, + coreTypes: coreTypes, + ); var moduleTree = kernel2jsCompiler.emitModule(component); // Compile JS AST to code. - return jsProgramToCode(moduleTree, ModuleFormat.amd, - emitDebugSymbols: true, - compiler: kernel2jsCompiler, - component: component); + return jsProgramToCode( + moduleTree, + ModuleFormat.amd, + emitDebugSymbols: true, + compiler: kernel2jsCompiler, + component: component, + ); } } @@ -93,8 +102,9 @@ } Future<ModuleSymbols> compileAndGetSymbols() async { - var result = - await TestCompiler(options).compile(input: input, packages: packages); + var result = await TestCompiler( + options, + ).compile(input: input, packages: packages); var symbols = result.symbols; if (symbols == null) { throw Exception('No symbols found in compilation result.');
diff --git a/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart index d0a107e..633ed51 100644 --- a/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart +++ b/pkg/dev_compiler/test/module_symbols/variable_symbols_test.dart
@@ -54,8 +54,10 @@ expect(variableSymbol.location!.scriptId, endsWith('/foo.dart')); }); test('start token position', () async { - expect(variableSymbol.location!.tokenPos, - source.indexOf('globalVariable')); + expect( + variableSymbol.location!.tokenPos, + source.indexOf('globalVariable'), + ); }); test('end token position', () async { expect(variableSymbol.location!.endTokenPos, source.lastIndexOf(';'));
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart index 6cd1703..cf3370a 100644 --- a/pkg/dev_compiler/test/nullable_inference_test.dart +++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -23,9 +23,10 @@ import 'package:test/test.dart'; const AstTextStrategy astTextStrategy = AstTextStrategy( - includeLibraryNamesInTypes: true, - includeLibraryNamesInMembers: true, - useMultiline: false); + includeLibraryNamesInTypes: true, + includeLibraryNamesInMembers: true, + useMultiline: false, +); void main() { test('empty main', () async { @@ -49,27 +50,36 @@ await expectNotNull('main() { print("hi"); }', ['"hi"']); }); test('List', () async { - await expectNotNull('main() { print([42, null]); }', - ['<dart.core::int?>[42, null]', '42']); - }); - test('const List', () async { - await expectNotNull('''library a; - const constList = [42, 99]; - main() { print(constList.first); }''', [ - 'a::constList.{dart.core::Iterable.first}', - 'a::constList', - 'const <dart.core::int>[42.0, 99.0]' + await expectNotNull('main() { print([42, null]); }', [ + '<dart.core::int?>[42, null]', + '42', ]); }); + test('const List', () async { + await expectNotNull( + '''library a; + const constList = [42, 99]; + main() { print(constList.first); }''', + [ + 'a::constList.{dart.core::Iterable.first}', + 'a::constList', + 'const <dart.core::int>[42.0, 99.0]', + ], + ); + }); test('Map', () async { - await expectNotNull('main() { print({"x": null}); }', - ['<dart.core::String, Null>{"x": null}', '"x"']); + await expectNotNull('main() { print({"x": null}); }', [ + '<dart.core::String, Null>{"x": null}', + '"x"', + ]); }); test('const Map', () async { - await expectNotNull('''library a; + await expectNotNull( + '''library a; const constMap = {"x": null}; main() { print(constMap); }''', - ['a::constMap', 'const <dart.core::String, Null>{"x": null}']); + ['a::constMap', 'const <dart.core::String, Null>{"x": null}'], + ); }); test('Symbol', () async { @@ -82,25 +92,35 @@ }); test('this', () async { - await expectNotNull( - 'library a; class C { m() { return this; } }', ['this', 'new a::C()']); + await expectNotNull('library a; class C { m() { return this; } }', [ + 'this', + 'new a::C()', + ]); }); test('is', () async { - await expectNotNull('main() { 42 is int; null is int; }', - ['42 is dart.core::int', '42', 'null is dart.core::int']); + await expectNotNull('main() { 42 is int; null is int; }', [ + '42 is dart.core::int', + '42', + 'null is dart.core::int', + ]); }); test('as', () async { // TODO(nshahan): How should we classify `null as int` in sound mode? // Seems non-nullable since it will throw if LHS is null. - await expectNotNull('main() { 42 as int; null as int; }', - ['42 as dart.core::int', '42', 'null as dart.core::int']); + await expectNotNull('main() { 42 as int; null as int; }', [ + '42 as dart.core::int', + '42', + 'null as dart.core::int', + ]); }); test('constructor', () async { - await expectNotNull('library a; class C {} main() { new C(); }', - ['new a::C()', 'new a::C()']); + await expectNotNull('library a; class C {} main() { new C(); }', [ + 'new a::C()', + 'new a::C()', + ]); }); group('operator', () { @@ -133,81 +153,93 @@ group('int', () { test('arithmetic', () async { await expectAllNotNull( - 'main() { -0; 1 + 2; 3 - 4; 5 * 6; 7 / 8; 9 % 10; 11 ~/ 12; }'); + 'main() { -0; 1 + 2; 3 - 4; 5 * 6; 7 / 8; 9 % 10; 11 ~/ 12; }', + ); }); test('bitwise', () async { await expectAllNotNull( - 'main() { 1 & 2; 3 | 4; 5 ^ 6; ~7; 8 << 9; 10 >> 11; }'); + 'main() { 1 & 2; 3 | 4; 5 ^ 6; ~7; 8 << 9; 10 >> 11; }', + ); }); test('comparison', () async { await expectAllNotNull('main() { 1 < 2; 3 > 4; 5 <= 6; 7 >= 8; }'); }); test('getters', () async { await expectAllNotNull( - 'main() { 1.isOdd; 1.isEven; 1.isNegative; 1.isNaN; 1.isInfinite; ' - '1.isFinite; 1.sign; 1.bitLength; 1.hashCode; }'); + 'main() { 1.isOdd; 1.isEven; 1.isNegative; 1.isNaN; 1.isInfinite; ' + '1.isFinite; 1.sign; 1.bitLength; 1.hashCode; }', + ); }); test('methods', () async { await expectAllNotNull( - 'main() { 1.compareTo(2); 1.remainder(2); 1.abs(); 1.toInt(); ' - '1.ceil(); 1.floor(); 1.truncate(); 1.round(); 1.ceilToDouble(); ' - '1.floorToDouble(); 1.truncateToDouble(); 1.roundToDouble(); ' - '1.toDouble(); 1.clamp(2, 2); 1.toStringAsFixed(2); ' - '1.toStringAsExponential(); 1.toStringAsPrecision(2); 1.toString(); ' - '1.toRadixString(2); 1.toUnsigned(2); 1.toSigned(2); 1.modPow(2, 2); ' - '1.modInverse(2); 1.gcd(2); }'); + 'main() { 1.compareTo(2); 1.remainder(2); 1.abs(); 1.toInt(); ' + '1.ceil(); 1.floor(); 1.truncate(); 1.round(); 1.ceilToDouble(); ' + '1.floorToDouble(); 1.truncateToDouble(); 1.roundToDouble(); ' + '1.toDouble(); 1.clamp(2, 2); 1.toStringAsFixed(2); ' + '1.toStringAsExponential(); 1.toStringAsPrecision(2); 1.toString(); ' + '1.toRadixString(2); 1.toUnsigned(2); 1.toSigned(2); 1.modPow(2, 2); ' + '1.modInverse(2); 1.gcd(2); }', + ); }); }); group('double', () { test('arithmetic', () async { await expectAllNotNull( - 'main() { -0.0; 1.0 + 2.0; 3.0 - 4.0; 5.0 * 6.0; 7.0 / 8.0; ' - '9.0 % 10.0; 11.0 ~/ 12.0; }'); + 'main() { -0.0; 1.0 + 2.0; 3.0 - 4.0; 5.0 * 6.0; 7.0 / 8.0; ' + '9.0 % 10.0; 11.0 ~/ 12.0; }', + ); }); test('comparison', () async { await expectAllNotNull( - 'main() { 1.0 < 2.0; 3.0 > 4.0; 5.0 <= 6.0; 7.0 >= 8.0; }'); + 'main() { 1.0 < 2.0; 3.0 > 4.0; 5.0 <= 6.0; 7.0 >= 8.0; }', + ); }); test('getters', () async { await expectAllNotNull( - 'main() { (1.0).isNegative; (1.0).isNaN; (1.0).isInfinite; ' - '(1.0).isFinite; (1.0).sign; (1.0).hashCode; }'); + 'main() { (1.0).isNegative; (1.0).isNaN; (1.0).isInfinite; ' + '(1.0).isFinite; (1.0).sign; (1.0).hashCode; }', + ); }); test('methods', () async { await expectAllNotNull( - 'main() { (1.0).compareTo(2.0); (1.0).remainder(2.0); (1.0).abs(); ' - '(1.0).toInt(); (1.0).ceil(); (1.0).floor(); (1.0).truncate(); ' - '(1.0).round(); (1.0).ceilToDouble(); (1.0).floorToDouble(); ' - '(1.0).truncateToDouble(); (1.0).roundToDouble(); (1.0).toDouble(); ' - '(1.0).clamp(2.0, 2.0); (1.0).toStringAsFixed(2); (1.0).toString(); ' - '(1.0).toStringAsExponential(); (1.0).toStringAsPrecision(2); }'); + 'main() { (1.0).compareTo(2.0); (1.0).remainder(2.0); (1.0).abs(); ' + '(1.0).toInt(); (1.0).ceil(); (1.0).floor(); (1.0).truncate(); ' + '(1.0).round(); (1.0).ceilToDouble(); (1.0).floorToDouble(); ' + '(1.0).truncateToDouble(); (1.0).roundToDouble(); (1.0).toDouble(); ' + '(1.0).clamp(2.0, 2.0); (1.0).toStringAsFixed(2); (1.0).toString(); ' + '(1.0).toStringAsExponential(); (1.0).toStringAsPrecision(2); }', + ); }); }); group('num', () { test('arithmetic', () async { await expectAllNotNull( - 'main() { num n = 1; -n; n + n; n - n; n * n; n / n; n % n; n % n; ' - 'n ~/ n; }'); + 'main() { num n = 1; -n; n + n; n - n; n * n; n / n; n % n; n % n; ' + 'n ~/ n; }', + ); }); test('comparison', () async { await expectAllNotNull( - 'main() { num n = 1; n < n; n > n; n <= n; n >= n; }'); + 'main() { num n = 1; n < n; n > n; n <= n; n >= n; }', + ); }); test('getters', () async { await expectAllNotNull( - 'main() { num n = 1; n.isNegative; n.isNaN; n.isInfinite; ' - 'n.isFinite; n.sign; n.hashCode; }'); + 'main() { num n = 1; n.isNegative; n.isNaN; n.isInfinite; ' + 'n.isFinite; n.sign; n.hashCode; }', + ); }); test('methods', () async { await expectAllNotNull( - 'main() { num n = 1; n.compareTo(n); n.remainder(n); n.abs(); ' - 'n.toInt(); n.ceil(); n.floor(); n.truncate(); ' - 'n.round(); n.ceilToDouble(); n.floorToDouble(); ' - 'n.truncateToDouble(); n.roundToDouble(); n.toDouble(); ' - 'n.clamp(n, n); n.toStringAsFixed(1); n.toString(); ' - 'n.toStringAsExponential(); n.toStringAsPrecision(1); }'); + 'main() { num n = 1; n.compareTo(n); n.remainder(n); n.abs(); ' + 'n.toInt(); n.ceil(); n.floor(); n.truncate(); ' + 'n.round(); n.ceilToDouble(); n.floorToDouble(); ' + 'n.truncateToDouble(); n.roundToDouble(); n.toDouble(); ' + 'n.clamp(n, n); n.toStringAsFixed(1); n.toString(); ' + 'n.toStringAsExponential(); n.toStringAsPrecision(1); }', + ); }); }); @@ -220,8 +252,9 @@ }); test('getters', () async { await expectAllNotNull( - 'main() { "".codeUnits; "".hashCode; "".isEmpty; "".isNotEmpty; ' - '"".length; "".runes; }'); + 'main() { "".codeUnits; "".hashCode; "".isEmpty; "".isNotEmpty; ' + '"".length; "".runes; }', + ); }); test('operators', () async { await expectAllNotNull('main() { "" + ""; "" * 2; "" == ""; "x"[0]; }'); @@ -264,30 +297,37 @@ }); test('identical', () async { - await expectNotNull('main() { identical(null, null); }', - ['dart.core::identical(null, null)']); + await expectNotNull('main() { identical(null, null); }', [ + 'dart.core::identical(null, null)', + ]); }); test('throw', () async { // It is a compile time error to throw nullable values in >=2.12.0 - await expectNotNull( - 'main() { print(throw "foo"); }', ['throw "foo"', '"foo"']); + await expectNotNull('main() { print(throw "foo"); }', [ + 'throw "foo"', + '"foo"', + ]); }); test('rethrow', () async { - await expectNotNull( - 'main() { try {} catch (e) { rethrow; } }', ['rethrow']); + await expectNotNull('main() { try {} catch (e) { rethrow; } }', [ + 'rethrow', + ]); }); test('function expression', () async { - await expectNotNull( - 'main() { () => null; f() {}; f; }', ['Null () => null', 'f']); + await expectNotNull('main() { () => null; f() {}; f; }', [ + 'Null () => null', + 'f', + ]); }); test('cascades (kernel BlockExpression)', () async { // `null..toString()` evaluates to `null` so it is nullable. - await expectNotNull( - 'main() { null..toString(); }', ['#0.{dart.core::Object.toString}()']); + await expectNotNull('main() { null..toString(); }', [ + '#0.{dart.core::Object.toString}()', + ]); await expectAllNotNull('main() { 1..toString(); }'); }); @@ -302,21 +342,28 @@ await expectNotNull('main() { var x; x = 1; print(x); }', ['x = 1', '1']); }); test('assignment non-null', () async { - await expectNotNull( - 'main() { var x = 42; x = 1; print(x); }', ['42', 'x = 1', '1', 'x']); + await expectNotNull('main() { var x = 42; x = 1; print(x); }', [ + '42', + 'x = 1', + '1', + 'x', + ]); }); test('assignment null', () async { await expectNotNull( - 'main() { var x = 42; x = null as dynamic; print(x); }', [ - '42', - 'x = (null as dynamic) as dart.core::int', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int', - 'x' - ]); + 'main() { var x = 42; x = null as dynamic; print(x); }', + [ + '42', + 'x = (null as dynamic) as dart.core::int', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int', + 'x', + ], + ); }); test('flow insensitive', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x = 1; if (true) { print(x); @@ -324,82 +371,96 @@ x = null as dynamic; print(x); } - }''', [ - '1', - 'true', - 'x', - 'x = (null as dynamic) as dart.core::int', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int', - 'x' - ]); + }''', + [ + '1', + 'true', + 'x', + 'x = (null as dynamic) as dart.core::int', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int', + 'x', + ], + ); }); test('declaration from variable', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x = 1; var y = x; print(y); x = null as dynamic; - }''', [ - '1', - 'x', - 'y', - 'x = (null as dynamic) as dart.core::int', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int' - ]); + }''', + [ + '1', + 'x', + 'y', + 'x = (null as dynamic) as dart.core::int', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int', + ], + ); }); test('declaration from variable nested', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x = 1; var y = (x = null as dynamic) == null; print(x); print(y); - }''', [ - '1', - '(x = (null as dynamic) as dart.core::int) == null', - 'x = (null as dynamic) as dart.core::int', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int', - 'x', - 'y' - ]); + }''', + [ + '1', + '(x = (null as dynamic) as dart.core::int) == null', + 'x = (null as dynamic) as dart.core::int', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int', + 'x', + 'y', + ], + ); }); test('declaration from variable transitive', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x = 1; var y = x; var z = y; print(z); x = null as dynamic; - }''', [ - '1', - 'x', - 'y', - 'z', - 'x = (null as dynamic) as dart.core::int', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int' - ]); + }''', + [ + '1', + 'x', + 'y', + 'z', + 'x = (null as dynamic) as dart.core::int', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int', + ], + ); }); test('declaration between variable transitive nested', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x = 1; var y = 1; var z = y = x; print(z); x = null as dynamic; - }''', [ - '1', - '1', - 'y = x', - 'x', - 'z', - 'x = (null as dynamic) as dart.core::int', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int' - ]); + }''', + [ + '1', + '1', + 'y = x', + 'x', + 'z', + 'x = (null as dynamic) as dart.core::int', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int', + ], + ); }); test('for not-null', () async { @@ -411,38 +472,43 @@ }); test('for nullable', () async { await expectNotNull( - '''main() { + '''main() { for (var i = 0; i < 10; i++) { if (i >= 10) i = null as dynamic; } }''', - // arithmetic operation results on `i` are themselves not null. - [ - '0', - 'i.{dart.core::num.<}(10)', - 'i', - '10', - 'i = i.{dart.core::num.+}(1)', - 'i.{dart.core::num.+}(1)', - 'i', - '1', - 'i.{dart.core::num.>=}(10)', - 'i', - '10', - 'i = (null as dynamic) as dart.core::int', - '(null as dynamic) as dart.core::int' - ]); + // arithmetic operation results on `i` are themselves not null. + [ + '0', + 'i.{dart.core::num.<}(10)', + 'i', + '10', + 'i = i.{dart.core::num.+}(1)', + 'i.{dart.core::num.+}(1)', + 'i', + '1', + 'i.{dart.core::num.>=}(10)', + 'i', + '10', + 'i = (null as dynamic) as dart.core::int', + '(null as dynamic) as dart.core::int', + ], + ); }); test('for-in', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { for (var i in []) { print(i); } - }''', ['<dynamic>[]']); + }''', + ['<dynamic>[]'], + ); }); test('inner functions', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var y = 0; f(x) { var g = () => print('g'); @@ -454,20 +520,23 @@ } f; f(42); - }''', [ - '0', - 'void () => dart.core::print("g")', - '"g"', - 'g', - 'y', - '1', - 'z', - 'f', - '42' - ]); + }''', + [ + '0', + 'void () => dart.core::print("g")', + '"g"', + 'g', + 'y', + '1', + 'z', + 'f', + '42', + ], + ); }); test('assignment to closure variable', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var y = 0; f(x) { y = x; @@ -475,14 +544,9 @@ f; f(42); print(y); - }''', [ - '0', - 'y = x as dart.core::int', - 'x as dart.core::int', - 'f', - '42', - 'y' - ]); + }''', + ['0', 'y = x as dart.core::int', 'x as dart.core::int', 'f', '42', 'y'], + ); }); test('declaration visits initializer', () async { @@ -498,41 +562,50 @@ }'''); }); test('assignment visits value with closure variable set', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x = () => 42; var y = (() => x = null as dynamic); - }''', [ - 'dart.core::int () => 42', - '42', - 'dynamic () => x = (null as dynamic) as dart.core::int Function()', - 'x = (null as dynamic) as dart.core::int Function()', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int Function()' - ]); + }''', + [ + 'dart.core::int () => 42', + '42', + 'dynamic () => x = (null as dynamic) as dart.core::int Function()', + 'x = (null as dynamic) as dart.core::int Function()', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int Function()', + ], + ); }); test('do not depend on unrelated variables', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x; var y = identical(x, null); y; // this is still non-null even though `x` is nullable - }''', ['dart.core::identical(x, null)', 'y']); + }''', + ['dart.core::identical(x, null)', 'y'], + ); }); test('do not depend on unrelated variables updated later', () async { - await expectNotNull('''main() { + await expectNotNull( + '''main() { var x = 1; var y = identical(x, 1); x = null as dynamic; y; // this is still non-null even though `x` is nullable - }''', [ - '1', - 'dart.core::identical(x, 1)', - 'x', - '1', - 'x = (null as dynamic) as dart.core::int', - // TODO(nshahan): How should we classify `null as int` in sound mode? - '(null as dynamic) as dart.core::int', - 'y' - ]); + }''', + [ + '1', + 'dart.core::identical(x, 1)', + 'x', + '1', + 'x = (null as dynamic) as dart.core::int', + // TODO(nshahan): How should we classify `null as int` in sound mode? + '(null as dynamic) as dart.core::int', + 'y', + ], + ); }); }); group('functions parameters in SDK', () { @@ -546,14 +619,20 @@ useAnnotations = false; }); test('optional with default value', () async { - await expectNotNull(''' + await expectNotNull( + ''' f(x, [y = 1]) { x; y; } - ''', ['1']); + ''', + ['1'], + ); }); test('named with default value', () async { - await expectNotNull(''' + await expectNotNull( + ''' f(x, {y = 1}) { x; y; } - ''', ['1']); + ''', + ['1'], + ); }); }); @@ -567,49 +646,59 @@ var imports = "import 'package:meta/meta.dart';"; group('(previously known kernel annotation bug)', () { test('variable without initializer', () async { - await expectNotNull( - '$imports main() { @notNull var x; print(x); }', ['x']); + await expectNotNull('$imports main() { @notNull var x; print(x); }', [ + 'x', + ]); }); test('variable with initializer', () async { await expectNotNull( - '$imports main() { @notNull var x = null; print(x); }', ['x']); + '$imports main() { @notNull var x = null; print(x); }', + ['x'], + ); }); test('parameters', () async { await expectNotNull( - '$imports f(@notNull x, [@notNull y, @notNull z = 42]) ' - '{ x; y; z; }', - ['42', 'x', 'y', 'z']); + '$imports f(@notNull x, [@notNull y, @notNull z = 42]) ' + '{ x; y; z; }', + ['42', 'x', 'y', 'z'], + ); }); test('named parameters', () async { await expectNotNull( - '$imports f({@notNull x, @notNull y = 42}) { x; y; }', - ['42', 'x', 'y']); + '$imports f({@notNull x, @notNull y = 42}) { x; y; }', + ['42', 'x', 'y'], + ); }); }); test('top-level field', () async { await expectNotNull( - // @notNull overrides the explicit nullable. - 'library a; $imports @notNull int? x; main() { x; }', - ['a::x']); + // @notNull overrides the explicit nullable. + 'library a; $imports @notNull int? x; main() { x; }', + ['a::x'], + ); }); test('getter', () async { await expectNotNull( - 'library b; $imports @notNull get x => null; main() { x; }', - ['b::x']); + 'library b; $imports @notNull get x => null; main() { x; }', + ['b::x'], + ); }); test('function', () async { await expectNotNull( - 'library a; $imports @notNull f() {} main() { f(); }', ['a::f()']); + 'library a; $imports @notNull f() {} main() { f(); }', + ['a::f()'], + ); }); test('method', () async { await expectNotNull( - 'library b; $imports class C { @notNull m() {} } ' - 'main() { var c = new C(); c.m(); }', - ['new b::C()', 'new b::C()', 'c.{b::C.m}()', 'c']); + 'library b; $imports class C { @notNull m() {} } ' + 'main() { var c = new C(); c.m(); }', + ['new b::C()', 'new b::C()', 'c.{b::C.m}()', 'c'], + ); }); }); } @@ -625,18 +714,18 @@ // ConstantExpressions print the table offset - we want to compare // against the underlying constant value instead. .map((e) { - if (e is ConstantExpression) { - var c = e.constant; - if (c is DoubleConstant && - c.value.isFinite && - c.value.truncateToDouble() == c.value) { - // Print integer values as integers - return BigInt.from(c.value).toString(); - } - return c.toText(astTextStrategy); - } - return e.toText(astTextStrategy); - }) + if (e is ConstantExpression) { + var c = e.constant; + if (c is DoubleConstant && + c.value.isFinite && + c.value.truncateToDouble() == c.value) { + // Print integer values as integers + return BigInt.from(c.value).toString(); + } + return c.toText(astTextStrategy); + } + return e.toText(astTextStrategy); + }) // Filter out our own NotNull annotations. The library prefix changes // per test, so just filter on the suffix. .where((s) => !s.endsWith('_NotNull{}')); @@ -672,8 +761,11 @@ _typeEnvironment = jsTypeRep.types; _staticTypeContext = StatefulStaticTypeContext.stacked(_typeEnvironment); _options = Options(moduleName: 'module_for_test'); - inference ??= - NullableInference(jsTypeRep, _staticTypeContext, options: _options); + inference ??= NullableInference( + jsTypeRep, + _staticTypeContext, + options: _options, + ); if (useAnnotations) { inference!.allowNotNullDeclarations = useAnnotations; @@ -746,8 +838,11 @@ @override void defaultExpression(Expression node) { - expect(inference!.isNullable(node), false, - reason: 'expression `$node` should be inferred as not-null'); + expect( + inference!.isNullable(node), + false, + reason: 'expression `$node` should be inferred as not-null', + ); super.defaultExpression(node); } } @@ -788,15 +883,14 @@ var packagesUri = Uri.file('/memory/.dart_tool/package_config.json'); var packagesFile = _fileSystem.entityForUri(packagesUri); if (!await packagesFile.exists()) { - packagesFile.writeAsStringSync(jsonEncode({ - 'configVersion': 2, - 'packages': [ - { - 'name': 'meta', - 'rootUri': '/memory/meta/lib', - }, - ], - })); + packagesFile.writeAsStringSync( + jsonEncode({ + 'configVersion': 2, + 'packages': [ + {'name': 'meta', 'rootUri': '/memory/meta/lib'}, + ], + }), + ); _fileSystem .entityForUri(Uri.file('/memory/meta/lib/meta.dart')) .writeAsStringSync(''' @@ -824,8 +918,9 @@ environmentDefines: addGeneratedVariables({}, enableAsserts: true), ); if (!identical(oldCompilerState, _compilerState)) inference = null; - var result = - await (fe.compile(_compilerState!, [mainUri], diagnosticMessageHandler)); + var result = await (fe.compile(_compilerState!, [ + mainUri, + ], diagnosticMessageHandler)); expect(succeeded, true); var librariesFromDill = result!.librariesFromDill;
diff --git a/pkg/dev_compiler/test/scopes/scope_test.dart b/pkg/dev_compiler/test/scopes/scope_test.dart index 225d2f6..639b20b 100644 --- a/pkg/dev_compiler/test/scopes/scope_test.dart +++ b/pkg/dev_compiler/test/scopes/scope_test.dart
@@ -17,15 +17,21 @@ Future<void> main(List<String> args) async { var dataDir = Directory.fromUri( - Platform.script.resolve('../../../front_end/test/scopes/data')); - await runTests<Features>(dataDir, - args: args, - createUriForFileName: createUriForFileName, - onFailure: onFailure, - runTest: runTestFor(const ScopeDataComputer(), [ - DdcTestConfig(ddcMarker, 'ddc', - experimentalFlags: {fe.ExperimentalFlag.inlineClass: true}) - ])); + Platform.script.resolve('../../../front_end/test/scopes/data'), + ); + await runTests<Features>( + dataDir, + args: args, + createUriForFileName: createUriForFileName, + onFailure: onFailure, + runTest: runTestFor(const ScopeDataComputer(), [ + DdcTestConfig( + ddcMarker, + 'ddc', + experimentalFlags: {fe.ExperimentalFlag.inlineClass: true}, + ), + ]), + ); } class Tags { @@ -40,11 +46,19 @@ const ScopeDataComputer(); @override - void computeMemberData(DdcTestResultData testResultData, Member member, - Map<Id, ActualData<Features>> actualMap, - {bool? verbose}) { - member.accept(ScopeDataExtractor( - member.enclosingLibrary, testResultData.compilerResult, actualMap)); + void computeMemberData( + DdcTestResultData testResultData, + Member member, + Map<Id, ActualData<Features>> actualMap, { + bool? verbose, + }) { + member.accept( + ScopeDataExtractor( + member.enclosingLibrary, + testResultData.compilerResult, + actualMap, + ), + ); } @override @@ -67,7 +81,11 @@ var location = node.location; if (location != null) { var scope = DartScopeBuilder.findScope( - component, library, location.line, location.column); + component, + library, + location.line, + location.column, + ); if (scope != null) { var features = Features(); if (scope.cls != null) { @@ -80,11 +98,14 @@ features.add(Tags.isStatic); } for (var typeParameter in scope.typeParameters) { - var printer = AstPrinter(const AstTextStrategy( + var printer = AstPrinter( + const AstTextStrategy( useQualifiedTypeParameterNames: true, useQualifiedTypeParameterNamesRecurseOnNamedLocalFunctions: true, - includeLibraryNamesInTypes: false)); + includeLibraryNamesInTypes: false, + ), + ); printer.writeTypeParameterName(typeParameter); features.addElement(Tags.typeParameter, printer.getText()); }
diff --git a/pkg/dev_compiler/test/shared_test_options.dart b/pkg/dev_compiler/test/shared_test_options.dart index e854bed..146b4e2 100644 --- a/pkg/dev_compiler/test/shared_test_options.dart +++ b/pkg/dev_compiler/test/shared_test_options.dart
@@ -14,32 +14,42 @@ class DevelopmentIncrementalCompiler extends fe.IncrementalCompiler { Uri entryPoint; - DevelopmentIncrementalCompiler(fe.CompilerOptions options, this.entryPoint, - [Uri? initializeFrom, - bool? outlineOnly, - fe.IncrementalSerializer? incrementalSerializer]) - : super( - fe.CompilerContext( - fe.ProcessedOptions(options: options, inputs: [entryPoint])), - initializeFrom, - outlineOnly, - incrementalSerializer); + DevelopmentIncrementalCompiler( + fe.CompilerOptions options, + this.entryPoint, [ + Uri? initializeFrom, + bool? outlineOnly, + fe.IncrementalSerializer? incrementalSerializer, + ]) : super( + fe.CompilerContext( + fe.ProcessedOptions(options: options, inputs: [entryPoint]), + ), + initializeFrom, + outlineOnly, + incrementalSerializer, + ); - DevelopmentIncrementalCompiler.fromComponent(fe.CompilerOptions options, - this.entryPoint, Component componentToInitializeFrom, - [bool? outlineOnly, fe.IncrementalSerializer? incrementalSerializer]) - : super.fromComponent( - fe.CompilerContext( - fe.ProcessedOptions(options: options, inputs: [entryPoint])), - componentToInitializeFrom, - outlineOnly, - incrementalSerializer); + DevelopmentIncrementalCompiler.fromComponent( + fe.CompilerOptions options, + this.entryPoint, + Component componentToInitializeFrom, [ + bool? outlineOnly, + fe.IncrementalSerializer? incrementalSerializer, + ]) : super.fromComponent( + fe.CompilerContext( + fe.ProcessedOptions(options: options, inputs: [entryPoint]), + ), + componentToInitializeFrom, + outlineOnly, + incrementalSerializer, + ); } class SetupCompilerOptions { static final sdkRoot = fe.computePlatformBinariesLocation(); - static final buildRoot = - fe.computePlatformBinariesLocation(forceBuildDir: true); + static final buildRoot = fe.computePlatformBinariesLocation( + forceBuildDir: true, + ); final List<String> errors = []; final List<String> diagnosticMessages = []; @@ -48,19 +58,25 @@ final bool canaryFeatures; final bool enableAsserts; - static fe.CompilerOptions _getOptions( - {required bool enableAsserts, required List<String> enableExperiments}) { + static fe.CompilerOptions _getOptions({ + required bool enableAsserts, + required List<String> enableExperiments, + }) { var options = fe.CompilerOptions() - ..verbose = false // set to true for debugging + ..verbose = + false // set to true for debugging ..sdkRoot = sdkRoot ..target = DevCompilerTarget(TargetFlags()) ..omitPlatform = true ..sdkSummary = buildRoot.resolve('ddc_outline.dill') - ..environmentDefines = - addGeneratedVariables({}, enableAsserts: enableAsserts) + ..environmentDefines = addGeneratedVariables( + {}, + enableAsserts: enableAsserts, + ) ..explicitExperimentalFlags = fe.parseExperimentalFlags( - fe.parseExperimentalArguments(enableExperiments), - onError: (e) => throw e); + fe.parseExperimentalArguments(enableExperiments), + onError: (e) => throw e, + ); return options; } @@ -70,8 +86,9 @@ this.canaryFeatures = false, List<String> enableExperiments = const [], }) : options = _getOptions( - enableAsserts: enableAsserts, - enableExperiments: enableExperiments) { + enableAsserts: enableAsserts, + enableExperiments: enableExperiments, + ) { options.onDiagnostic = (fe.DiagnosticMessage m) { diagnosticMessages.addAll(m.plainTextFormatted); if (m.severity == fe.Severity.error ||
diff --git a/pkg/dev_compiler/test/sourcemap/common.dart b/pkg/dev_compiler/test/sourcemap/common.dart index 8baf599..aa0773f 100644 --- a/pkg/dev_compiler/test/sourcemap/common.dart +++ b/pkg/dev_compiler/test/sourcemap/common.dart
@@ -76,8 +76,12 @@ @override Future<Result<Data>> run(Data data, ChainContext context) async { var outWrapperPath = p.join(data.outDir.path, 'wrapper.js'); - var runResult = runD8AndStep(data.outDir.path, data.testFileName, data.code, - ['--module', outWrapperPath]); + var runResult = runD8AndStep( + data.outDir.path, + data.testFileName, + data.code, + ['--module', outWrapperPath], + ); data.d8Output = (runResult.stdout as String).split('\n'); return pass(data); } @@ -103,7 +107,7 @@ for (var outDir in const [ 'out/ReleaseX64', 'xcodebuild/ReleaseX64', - 'xcodebuild/ReleaseARM64' + 'xcodebuild/ReleaseARM64', ]) { var tryPath = p.join(outerDir, outDir, relative); var file = File(tryPath);
diff --git a/pkg/dev_compiler/test/sourcemap/ddc_common.dart b/pkg/dev_compiler/test/sourcemap/ddc_common.dart index db2ea5e..1812e24 100644 --- a/pkg/dev_compiler/test/sourcemap/ddc_common.dart +++ b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
@@ -40,7 +40,10 @@ data.outDir = await Directory.systemTemp.createTemp('ddc_step_test'); data.code = AnnotatedCode.fromText( - File(inputFile).readAsStringSync(), commentStart, commentEnd); + File(inputFile).readAsStringSync(), + commentStart, + commentEnd, + ); data.testFileName = 'test.dart'; var outDirUri = data.outDir.uri; var testFile = outDirUri.resolve(data.testFileName); @@ -70,12 +73,16 @@ data.outDir = await Directory.systemTemp.createTemp('stacktrace-test'); var code = await File.fromUri(data.uri).readAsString(); var test = processTestCode(code, knownMarkers); - await testStackTrace(test, marker, _compile, - jsPreambles: _getPreambles, - useJsMethodNamesOnAbsence: true, - jsNameConverter: _convertName, - forcedTmpDir: data.outDir, - verbose: true); + await testStackTrace( + test, + marker, + _compile, + jsPreambles: _getPreambles, + useJsMethodNamesOnAbsence: true, + jsNameConverter: _convertName, + forcedTmpDir: data.outDir, + verbose: true, + ); return pass(data); } @@ -89,7 +96,7 @@ return [ '--module', _getWrapperPathFromDirectoryFile(Uri.file(input)).toFilePath(), - '--' + '--', ]; } @@ -130,13 +137,14 @@ return _cachedDdcDir ??= search(); } -String getWrapperContent( - {required Uri sdkJsFile, - required Uri? ddcModuleLoaderFile, - required Uri inputFile, - required Uri outputFile, - required String moduleFormat, - required bool canary}) { +String getWrapperContent({ + required Uri sdkJsFile, + required Uri? ddcModuleLoaderFile, + required Uri inputFile, + required Uri outputFile, + required String moduleFormat, + required bool canary, +}) { assert(sdkJsFile.isAbsolute); var imports = ''; String mainClosure; @@ -144,14 +152,16 @@ var inputPath = inputFile.path; inputPath = inputPath.substring(0, inputPath.lastIndexOf('.')); final inputFileNameNoExt = pathToJSIdentifier(inputPath); - imports = ''' + imports = + ''' import { dart, _isolate_helper } from '${uriPathForwardSlashed(sdkJsFile)}'; import { $inputFileNameNoExt } from '${outputFile.pathSegments.last}'; '''; mainClosure = '$inputFileNameNoExt.main'; } else { assert(moduleFormat == 'ddc' && canary); - imports = ''' + imports = + ''' load('${uriPathForwardSlashed(ddcModuleLoaderFile!)}'); load('${uriPathForwardSlashed(sdkJsFile)}'); load('${uriPathForwardSlashed(outputFile)}'); @@ -185,46 +195,56 @@ '''; } -void createHtmlWrapper( - {required Uri inputFile, - required Uri sdkJsFile, - required Uri outputFile, - required String jsContent, - required String outputFilename, - required String moduleFormat, - required bool canary}) { +void createHtmlWrapper({ + required Uri inputFile, + required Uri sdkJsFile, + required Uri outputFile, + required String jsContent, + required String outputFilename, + required String moduleFormat, + required bool canary, +}) { // For debugging via HTML, Chrome and ./pkg/test_runner/bin/http_server.dart. var sdkRootPath = sdkRoot!.path; var sdkFile = File(p.relative(sdkJsFile.path, from: sdkRootPath)); var jsRootDart = '/root_dart/${sdkFile.uri}'; File.fromUri(outputFile.resolve('$outputFilename.html.js')).writeAsStringSync( - jsContent.replaceFirst("from 'dart_sdk.js'", "from '$jsRootDart'")); - File.fromUri(outputFile.resolve('$outputFilename.html.html')) - .writeAsStringSync(getWrapperHtmlContent( - inputFile: inputFile, - jsRootDart: jsRootDart, - outFileRootBuild: '/root_build/$outputFilename.html.js', - moduleFormat: moduleFormat, - canary: canary)); + jsContent.replaceFirst("from 'dart_sdk.js'", "from '$jsRootDart'"), + ); + File.fromUri( + outputFile.resolve('$outputFilename.html.html'), + ).writeAsStringSync( + getWrapperHtmlContent( + inputFile: inputFile, + jsRootDart: jsRootDart, + outFileRootBuild: '/root_build/$outputFilename.html.js', + moduleFormat: moduleFormat, + canary: canary, + ), + ); - print('You should now be able to run\n\n' - 'dart $sdkRootPath/pkg/test_runner/bin/http_server.dart -p 39550 ' - '--network 127.0.0.1 ' - '--build-directory=${outputFile.resolve('.').toFilePath()}' - '\n\nand go to\n\n' - 'http://127.0.0.1:39550/root_build/$outputFilename.html.html' - '\n\nto step through via the browser.'); + print( + 'You should now be able to run\n\n' + 'dart $sdkRootPath/pkg/test_runner/bin/http_server.dart -p 39550 ' + '--network 127.0.0.1 ' + '--build-directory=${outputFile.resolve('.').toFilePath()}' + '\n\nand go to\n\n' + 'http://127.0.0.1:39550/root_build/$outputFilename.html.html' + '\n\nto step through via the browser.', + ); } -String getWrapperHtmlContent( - {required Uri inputFile, - required String jsRootDart, - required String outFileRootBuild, - required String moduleFormat, - required bool canary}) { +String getWrapperHtmlContent({ + required Uri inputFile, + required String jsRootDart, + required String outFileRootBuild, + required String moduleFormat, + required bool canary, +}) { String callMain; if (moduleFormat == 'es6') { - callMain = ''' + callMain = + ''' import { dart, _isolate_helper } from '$jsRootDart'; import { test } from '$outFileRootBuild'; let main = test.main; @@ -253,9 +273,11 @@ Uri selfUri = currentMirrorSystem() .findLibrary(#dev_compiler.test.sourcemap.ddc_common) .uri; -String d8Preambles = File.fromUri(selfUri.resolve( - '../../../../sdk/lib/_internal/js_dev_runtime/private/preambles/d8.js')) - .readAsStringSync(); +String d8Preambles = File.fromUri( + selfUri.resolve( + '../../../../sdk/lib/_internal/js_dev_runtime/private/preambles/d8.js', + ), +).readAsStringSync(); /// Transforms a path to a valid JS identifier. /// @@ -266,11 +288,13 @@ if (path.startsWith('/') || path.startsWith('\\')) { path = path.substring(1, path.length); } - return _toJSIdentifier(path - .replaceAll('\\', '__') - .replaceAll('/', '__') - .replaceAll('..', '__') - .replaceAll('-', '_')); + return _toJSIdentifier( + path + .replaceAll('\\', '__') + .replaceAll('/', '__') + .replaceAll('..', '__') + .replaceAll('-', '_'), + ); } /// Escape [name] to make it into a valid identifier.
diff --git a/pkg/dev_compiler/test/sourcemap/sourcemaps_suite.dart b/pkg/dev_compiler/test/sourcemap/sourcemaps_suite.dart index 24e08f8..887b3e9 100644 --- a/pkg/dev_compiler/test/sourcemap/sourcemaps_suite.dart +++ b/pkg/dev_compiler/test/sourcemap/sourcemaps_suite.dart
@@ -14,7 +14,9 @@ import 'ddc_common.dart'; Future<ChainContext> createContext( - Chain suite, Map<String, String> environment) async { + Chain suite, + Map<String, String> environment, +) async { return SourceMapContext(environment); } @@ -48,8 +50,12 @@ final String moduleFormat; final bool canary; - const DevCompilerRunner(this.context, - {this.debugging = false, this.moduleFormat = 'es6', this.canary = false}); + const DevCompilerRunner( + this.context, { + this.debugging = false, + this.moduleFormat = 'es6', + this.canary = false, + }); @override Future<Null> run(Uri inputFile, Uri outputFile, Uri outWrapperFile) async { @@ -60,14 +66,15 @@ } else { assert(moduleFormat == 'ddc' && canary); sdkJsFile = findInOutDir('gen/utils/ddc/canary/sdk/ddc/dart_sdk.js').uri; - ddcModuleLoaderFile = - findInOutDir('dart-sdk/lib/dev_compiler/ddc/ddc_module_loader.js') - .uri; + ddcModuleLoaderFile = findInOutDir( + 'dart-sdk/lib/dev_compiler/ddc/ddc_module_loader.js', + ).uri; } var ddcSdkSummary = findInOutDir('ddc_outline.dill'); - var packageConfigPath = - sdkRoot!.uri.resolve('.dart_tool/package_config.json').toFilePath(); + var packageConfigPath = sdkRoot!.uri + .resolve('.dart_tool/package_config.json') + .toFilePath(); var args = <String>[ '--batch', '--packages=$packageConfigPath', @@ -76,13 +83,15 @@ '--dart-sdk-summary=${ddcSdkSummary.path}', '-o', outputFile.toFilePath(), - inputFile.toFilePath() + inputFile.toFilePath(), ]; var succeeded = false; try { - var result = await compile(ParsedArguments.from(args), - compilerState: context.compilerState); + var result = await compile( + ParsedArguments.from(args), + compilerState: context.compilerState, + ); context.compilerState = result.compilerState as fe.InitializedCompilerState?; succeeded = result.success; @@ -101,27 +110,35 @@ } var jsContent = File.fromUri(outputFile).readAsStringSync(); - File.fromUri(outputFile).writeAsStringSync(jsContent.replaceFirst( - "from 'dart_sdk.js'", "from '${uriPathForwardSlashed(sdkJsFile)}'")); + File.fromUri(outputFile).writeAsStringSync( + jsContent.replaceFirst( + "from 'dart_sdk.js'", + "from '${uriPathForwardSlashed(sdkJsFile)}'", + ), + ); if (debugging) { createHtmlWrapper( - inputFile: inputFile, - sdkJsFile: sdkJsFile, - outputFile: outputFile, - jsContent: jsContent, - outputFilename: outputFile.pathSegments.last, - moduleFormat: moduleFormat, - canary: canary); + inputFile: inputFile, + sdkJsFile: sdkJsFile, + outputFile: outputFile, + jsContent: jsContent, + outputFilename: outputFile.pathSegments.last, + moduleFormat: moduleFormat, + canary: canary, + ); } - File.fromUri(outWrapperFile).writeAsStringSync(getWrapperContent( + File.fromUri(outWrapperFile).writeAsStringSync( + getWrapperContent( sdkJsFile: sdkJsFile, ddcModuleLoaderFile: ddcModuleLoaderFile, inputFile: inputFile, outputFile: outputFile, moduleFormat: moduleFormat, - canary: canary)); + canary: canary, + ), + ); } }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_library_bundle_suite.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_library_bundle_suite.dart index 4574d95..c2ce301 100644 --- a/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_library_bundle_suite.dart +++ b/pkg/dev_compiler/test/sourcemap/stacktrace_ddc_library_bundle_suite.dart
@@ -7,7 +7,9 @@ import 'stacktrace_suite.dart'; Future<ChainContext> _createContext( - Chain suite, Map<String, String> environment) async { + Chain suite, + Map<String, String> environment, +) async { return StackTraceContext(moduleFormat: 'ddc', canary: true); }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_suite.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_suite.dart index 531f08a..86ba0f0 100644 --- a/pkg/dev_compiler/test/sourcemap/stacktrace_suite.dart +++ b/pkg/dev_compiler/test/sourcemap/stacktrace_suite.dart
@@ -10,7 +10,9 @@ import 'sourcemaps_suite.dart'; Future<ChainContext> _createContext( - Chain suite, Map<String, String> environment) async { + Chain suite, + Map<String, String> environment, +) async { return StackTraceContext(moduleFormat: 'es6', canary: false); } @@ -32,10 +34,15 @@ const Setup(), const SetCwdToSdkRoot(), TestStackTrace( - DevCompilerRunner(this, - debugging: false, moduleFormat: moduleFormat, canary: canary), - 'ddc', - ['ddc']), + DevCompilerRunner( + this, + debugging: false, + moduleFormat: moduleFormat, + canary: canary, + ), + 'ddc', + ['ddc'], + ), ]; } }
diff --git a/pkg/dev_compiler/test/string_to_uri_test.dart b/pkg/dev_compiler/test/string_to_uri_test.dart index 396abb5..343fb56 100755 --- a/pkg/dev_compiler/test/string_to_uri_test.dart +++ b/pkg/dev_compiler/test/string_to_uri_test.dart
@@ -17,80 +17,107 @@ group('sourcePathToUri', () { test('various URL schemes', () { expect(sourcePathToUri('dart:io').toString(), 'dart:io'); - expect(sourcePathToUri('package:expect/expect.dart').toString(), - 'package:expect/expect.dart'); + expect( + sourcePathToUri('package:expect/expect.dart').toString(), + 'package:expect/expect.dart', + ); expect(sourcePathToUri('foobar:whatnot').toString(), 'foobar:whatnot'); }); test('full Windows path', () { expect( - sourcePathToUri('C:\\full\\windows\\path.foo', windows: true) - .toString(), - 'file:///C:/full/windows/path.foo'); + sourcePathToUri( + 'C:\\full\\windows\\path.foo', + windows: true, + ).toString(), + 'file:///C:/full/windows/path.foo', + ); expect( - sourcePathToUri('C:/full/windows/path.foo', windows: true).toString(), - 'file:///C:/full/windows/path.foo'); + sourcePathToUri('C:/full/windows/path.foo', windows: true).toString(), + 'file:///C:/full/windows/path.foo', + ); }); test('relative Windows path', () { expect( - sourcePathToUri('partial\\windows\\path.foo', windows: true) - .toString(), - 'file://$currentDir/partial/windows/path.foo'); + sourcePathToUri('partial\\windows\\path.foo', windows: true).toString(), + 'file://$currentDir/partial/windows/path.foo', + ); }); test('full unix path', () { expect( - sourcePathToUri('/full/path/to/foo.bar', windows: false).toString(), - 'file:///full/path/to/foo.bar'); + sourcePathToUri('/full/path/to/foo.bar', windows: false).toString(), + 'file:///full/path/to/foo.bar', + ); }); test('relative unix path', () { expect( - sourcePathToUri('partial/path/to/foo.bar', windows: false).toString(), - 'file://$currentDir/partial/path/to/foo.bar'); + sourcePathToUri('partial/path/to/foo.bar', windows: false).toString(), + 'file://$currentDir/partial/path/to/foo.bar', + ); }); }); group('sourcePathToRelativeUri', () { test('various URL schemes', () { expect(sourcePathToRelativeUri('dart:io').toString(), 'dart:io'); - expect(sourcePathToRelativeUri('package:expect/expect.dart').toString(), - 'package:expect/expect.dart'); - expect(sourcePathToRelativeUri('foobar:whatnot').toString(), - 'foobar:whatnot'); + expect( + sourcePathToRelativeUri('package:expect/expect.dart').toString(), + 'package:expect/expect.dart', + ); + expect( + sourcePathToRelativeUri('foobar:whatnot').toString(), + 'foobar:whatnot', + ); }); test('full Windows path', () { expect( - sourcePathToRelativeUri('C:\\full\\windows\\path.foo', windows: true) - .toString(), - 'file:///C:/full/windows/path.foo'); + sourcePathToRelativeUri( + 'C:\\full\\windows\\path.foo', + windows: true, + ).toString(), + 'file:///C:/full/windows/path.foo', + ); expect( - sourcePathToRelativeUri('C:/full/windows/path.foo', windows: true) - .toString(), - 'file:///C:/full/windows/path.foo'); + sourcePathToRelativeUri( + 'C:/full/windows/path.foo', + windows: true, + ).toString(), + 'file:///C:/full/windows/path.foo', + ); }); test('relative Windows path', () { expect( - sourcePathToRelativeUri('partial\\windows\\path.foo', windows: true) - .toString(), - 'partial/windows/path.foo'); + sourcePathToRelativeUri( + 'partial\\windows\\path.foo', + windows: true, + ).toString(), + 'partial/windows/path.foo', + ); }); test('full unix path', () { expect( - sourcePathToRelativeUri('/full/path/to/foo.bar', windows: false) - .toString(), - 'file:///full/path/to/foo.bar'); + sourcePathToRelativeUri( + '/full/path/to/foo.bar', + windows: false, + ).toString(), + 'file:///full/path/to/foo.bar', + ); }); test('relative unix path', () { expect( - sourcePathToRelativeUri('partial/path/to/foo.bar', windows: false) - .toString(), - 'partial/path/to/foo.bar'); + sourcePathToRelativeUri( + 'partial/path/to/foo.bar', + windows: false, + ).toString(), + 'partial/path/to/foo.bar', + ); }); }); }
diff --git a/pkg/dev_compiler/test/worker/worker_test.dart b/pkg/dev_compiler/test/worker/worker_test.dart index db86350..3a0c465 100644 --- a/pkg/dev_compiler/test/worker/worker_test.dart +++ b/pkg/dev_compiler/test/worker/worker_test.dart
@@ -14,26 +14,28 @@ Directory tmp = Directory.systemTemp.createTempSync('ddc_worker_test'); File file(String path) => File.fromUri(tmp.uri.resolve(path)); String _resolvePath(String executableRelativePath) { - return Uri.file(Platform.resolvedExecutable) - .resolve(executableRelativePath) - .toFilePath(); + return Uri.file( + Platform.resolvedExecutable, + ).resolve(executableRelativePath).toFilePath(); } void main() { var baseArgs = <String>[]; var sdkPath = p.dirname(Platform.executable); var dartAotRuntime = p.absolute( - sdkPath, - Platform.isWindows - ? 'dartaotruntime_product.exe' - : 'dartaotruntime_product'); + sdkPath, + Platform.isWindows + ? 'dartaotruntime_product.exe' + : 'dartaotruntime_product', + ); var snapshotName = _resolvePath('gen/dartdevc_aot_product.dart.snapshot'); if (!File(dartAotRuntime).existsSync()) { dartAotRuntime = p.absolute( - sdkPath, - Platform.isWindows - ? 'dartaotruntime_product.exe' - : 'dartaotruntime_product'); + sdkPath, + Platform.isWindows + ? 'dartaotruntime_product.exe' + : 'dartaotruntime_product', + ); snapshotName = _resolvePath('gen/dartdevc_aot.dart.snapshot'); } final executableArgs = <String>[ @@ -99,9 +101,11 @@ response = await _readResponse(messageGrouper); expect(response.exitCode, 1, reason: response.output); expect( - response.output, - contains( - 'A value of type \'String\' can\'t be assigned to a variable of type \'int\'.')); + response.output, + contains( + 'A value of type \'String\' can\'t be assigned to a variable of type \'int\'.', + ), + ); process.kill(); @@ -127,8 +131,10 @@ var result = Process.runSync(dartAotRuntime, args); expect(result.exitCode, 64); - expect(result.stdout, - contains('Could not find an option named "--does-not-exist"')); + expect( + result.stdout, + contains('Could not find an option named "--does-not-exist"'), + ); expect(result.stderr, isEmpty); expect(outputJsFile.existsSync(), isFalse); }); @@ -186,8 +192,10 @@ setUp(() { greetingDart.writeAsStringSync('String greeting = "hello";'); - helloDart.writeAsStringSync('import "greeting.dart";' - 'main() => print(greeting);'); + helloDart.writeAsStringSync( + 'import "greeting.dart";' + 'main() => print(greeting);', + ); }); tearDown(() { @@ -202,15 +210,11 @@ test('can compile in basic mode', () { var result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-source-map', - '-o', - greetingJS.path, - greetingDart.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + ['--no-source-map', '-o', greetingJS.path, greetingDart.path], + ); expect(result.stdout, isEmpty); expect(result.stderr, isEmpty); expect(result.exitCode, EXIT_CODE_OK); @@ -218,18 +222,19 @@ expect(greetingSummary.existsSync(), isTrue); result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-source-map', - '--no-summarize', - '-s', - greetingSummary.path, - '-o', - helloJS.path, - helloDart.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + [ + '--no-source-map', + '--no-summarize', + '-s', + greetingSummary.path, + '-o', + helloJS.path, + helloDart.path, + ], + ); expect(result.exitCode, EXIT_CODE_OK); expect(result.stdout, isEmpty); expect(result.stderr, isEmpty); @@ -238,15 +243,11 @@ test('reports error on overlapping summaries', () { var result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-source-map', - '-o', - greetingJS.path, - greetingDart.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + ['--no-source-map', '-o', greetingJS.path, greetingDart.path], + ); expect(result.exitCode, EXIT_CODE_OK); expect(result.stdout, isEmpty); expect(result.stderr, isEmpty); @@ -254,15 +255,11 @@ expect(greetingSummary.existsSync(), isTrue); result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-source-map', - '-o', - greeting2JS.path, - greetingDart.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + ['--no-source-map', '-o', greeting2JS.path, greetingDart.path], + ); expect(result.exitCode, EXIT_CODE_OK); expect(result.stdout, isEmpty); expect(result.stderr, isEmpty); @@ -270,20 +267,21 @@ expect(greeting2Summary.existsSync(), isTrue); result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-source-map', - '--no-summarize', - '-s', - greetingSummary.path, - '-s', - greeting2Summary.path, - '-o', - helloJS.path, - helloDart.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + [ + '--no-source-map', + '--no-summarize', + '-s', + greetingSummary.path, + '-s', + greeting2Summary.path, + '-o', + helloJS.path, + helloDart.path, + ], + ); // TODO(vsm): Re-enable when we turn this check back on. expect(result.exitCode, 0); // expect(result.exitCode, 65); @@ -304,30 +302,25 @@ test('incorrect usage', () { var result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - 'oops', - ]); + dartAotRuntime, + executableArgs + baseArgs + ['oops'], + ); expect(result.exitCode, 64); expect( - result.stdout, contains('Please specify the output file location.')); + result.stdout, + contains('Please specify the output file location.'), + ); expect(result.stdout, isNot(contains('#0'))); }); test('compile errors', () { badFileDart.writeAsStringSync('main() => "hello world"'); var result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-source-map', - '-o', - badFileJs.path, - badFileDart.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + ['--no-source-map', '-o', badFileJs.path, badFileDart.path], + ); expect(result.exitCode, 1); expect(result.stdout, contains(RegExp(r"Expected (to find )?\';\'"))); }); @@ -340,11 +333,15 @@ final outJS = file('output.js'); setUp(() { - partFile.writeAsStringSync('part of hello;\n' - 'String greeting = "hello";'); - libraryFile.writeAsStringSync('library hello;\n' - 'part "greeting.dart";\n' - 'main() => print(greeting);\n'); + partFile.writeAsStringSync( + 'part of hello;\n' + 'String greeting = "hello";', + ); + libraryFile.writeAsStringSync( + 'library hello;\n' + 'part "greeting.dart";\n' + 'main() => print(greeting);\n', + ); }); tearDown(() { @@ -355,17 +352,18 @@ test('works if part and library supplied', () { var result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-summarize', - '--no-source-map', - '-o', - outJS.path, - partFile.path, - libraryFile.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + [ + '--no-summarize', + '--no-source-map', + '-o', + outJS.path, + partFile.path, + libraryFile.path, + ], + ); expect(result.stdout, isEmpty); expect(result.stderr, isEmpty); expect(result.exitCode, 0); @@ -374,16 +372,17 @@ test('works if part is not supplied', () { var result = Process.runSync( - dartAotRuntime, - executableArgs + - baseArgs + - [ - '--no-summarize', - '--no-source-map', - '-o', - outJS.path, - libraryFile.path, - ]); + dartAotRuntime, + executableArgs + + baseArgs + + [ + '--no-summarize', + '--no-source-map', + '-o', + outJS.path, + libraryFile.path, + ], + ); expect(result.stdout, isEmpty); expect(result.stderr, isEmpty); expect(result.exitCode, 0);
diff --git a/pkg/dev_compiler/tool/hotreload/hot_reload_helper.dart b/pkg/dev_compiler/tool/hotreload/hot_reload_helper.dart index 7e82e8a..e02185d 100644 --- a/pkg/dev_compiler/tool/hotreload/hot_reload_helper.dart +++ b/pkg/dev_compiler/tool/hotreload/hot_reload_helper.dart
@@ -82,23 +82,28 @@ /// Create a helper that is bound to the current VM and isolate. static Future<HotReloadHelper> create() async { - final info = - await Service.controlWebServer(enable: true, silenceOutput: true); + final info = await Service.controlWebServer( + enable: true, + silenceOutput: true, + ); final observatoryUri = info.serverUri; if (observatoryUri == null) { - print('Error: no VM service found. ' - 'Please invoke dart with `--enable-vm-service`.'); + print( + 'Error: no VM service found. ' + 'Please invoke dart with `--enable-vm-service`.', + ); io.exit(1); } final wsUri = 'ws://${observatoryUri.authority}${observatoryUri.path}ws'; final vmService = await vm_service_io.vmServiceConnectUri(wsUri); final vm = await vmService.getVM(); - final id = - vm.isolates!.firstWhere((isolate) => !isolate.isSystemIsolate!).id!; + final id = vm.isolates! + .firstWhere((isolate) => !isolate.isSystemIsolate!) + .id!; return HotReloadHelper._(vmService, id); } - /// Triggter a hot-reload on the current isolate. + /// Trigger a hot-reload on the current isolate. Future<ReloadReport> reload() => _vmService.reloadSources(_id); }
diff --git a/pkg/dev_compiler/web/source_map_stack_trace.dart b/pkg/dev_compiler/web/source_map_stack_trace.dart index fac6de0..9ebe1180 100644 --- a/pkg/dev_compiler/web/source_map_stack_trace.dart +++ b/pkg/dev_compiler/web/source_map_stack_trace.dart
@@ -14,60 +14,75 @@ /// /// [roots] are the paths (usually `http:` URI strings) that DDC applications /// are served from. This is used to identify sdk and package URIs. -StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace, - {required List<String?> roots}) { +StackTrace mapStackTrace( + Mapping sourceMap, + StackTrace stackTrace, { + required List<String?> roots, +}) { if (stackTrace is Chain) { - return Chain(stackTrace.traces.map((trace) { - return Trace.from(mapStackTrace(sourceMap, trace, roots: roots)); - })); + return Chain( + stackTrace.traces.map((trace) { + return Trace.from(mapStackTrace(sourceMap, trace, roots: roots)); + }), + ); } var trace = Trace.from(stackTrace); - return Trace(trace.frames.map((frame) { - // If there's no line information, there's no way to translate this frame. - // We could return it as-is, but these lines are usually not useful anyways. - if (frame.line == null) return null; + return Trace( + trace.frames.map((frame) { + // If there's no line information, there's no way to translate this frame. + // We could return it as-is, but these lines are usually not useful anyways. + if (frame.line == null) return null; - // If there's no column, try using the first column of the line. - var column = frame.column ?? 0; + // If there's no column, try using the first column of the line. + var column = frame.column ?? 0; - // Subtract 1 because stack traces use 1-indexed lines and columns and - // source maps uses 0-indexed. - var span = sourceMap.spanFor(frame.line! - 1, column - 1, - uri: frame.uri.toString()); + // Subtract 1 because stack traces use 1-indexed lines and columns and + // source maps uses 0-indexed. + var span = sourceMap.spanFor( + frame.line! - 1, + column - 1, + uri: frame.uri.toString(), + ); - // If we can't find a source span, ignore the frame. It's probably something - // internal that the user doesn't care about. - if (span == null) return null; + // If we can't find a source span, ignore the frame. It's probably something + // internal that the user doesn't care about. + if (span == null) return null; - var sourceUrl = span.sourceUrl.toString(); - for (var root in roots) { - if (root != null && p.url.isWithin(root, sourceUrl)) { - var relative = p.url.relative(sourceUrl, from: root); - if (relative.contains('dart:')) { - sourceUrl = relative.substring(relative.indexOf('dart:')); - break; - } - var packageRoot = '$root/packages'; - if (p.url.isWithin(packageRoot, sourceUrl)) { - sourceUrl = 'package:${p.url.relative(sourceUrl, from: packageRoot)}'; - break; + var sourceUrl = span.sourceUrl.toString(); + for (var root in roots) { + if (root != null && p.url.isWithin(root, sourceUrl)) { + var relative = p.url.relative(sourceUrl, from: root); + if (relative.contains('dart:')) { + sourceUrl = relative.substring(relative.indexOf('dart:')); + break; + } + var packageRoot = '$root/packages'; + if (p.url.isWithin(packageRoot, sourceUrl)) { + sourceUrl = + 'package:${p.url.relative(sourceUrl, from: packageRoot)}'; + break; + } } } - } - if (!sourceUrl.startsWith('dart:') && - !sourceUrl.startsWith('package:') && - sourceUrl.contains('dart_sdk')) { - // This compresses the long dart_sdk URLs if SDK source maps are missing. - // It's no longer linkable, but neither are the properly mapped ones - // above. - sourceUrl = 'dart:sdk_internal'; - } + if (!sourceUrl.startsWith('dart:') && + !sourceUrl.startsWith('package:') && + sourceUrl.contains('dart_sdk')) { + // This compresses the long dart_sdk URLs if SDK source maps are missing. + // It's no longer linkable, but neither are the properly mapped ones + // above. + sourceUrl = 'dart:sdk_internal'; + } - return Frame(Uri.parse(sourceUrl), span.start.line + 1, - span.start.column + 1, _prettifyMember(frame.member!)); - }).nonNulls); + return Frame( + Uri.parse(sourceUrl), + span.start.line + 1, + span.start.column + 1, + _prettifyMember(frame.member!), + ); + }).nonNulls, + ); } final escapedPipe = '\$124'; @@ -122,7 +137,7 @@ /// that an escaped sequence precedes a number literal in the JS name. String _unescape(String name) { return name.replaceAllMapped( - RegExp(r'\$[0-9]+'), - (m) => - String.fromCharCode(int.parse(name.substring(m.start + 1, m.end)))); + RegExp(r'\$[0-9]+'), + (m) => String.fromCharCode(int.parse(name.substring(m.start + 1, m.end))), + ); }
diff --git a/pkg/dev_compiler/web/stack_trace_mapper.dart b/pkg/dev_compiler/web/stack_trace_mapper.dart index 5c7f0e5..4cc4136 100644 --- a/pkg/dev_compiler/web/stack_trace_mapper.dart +++ b/pkg/dev_compiler/web/stack_trace_mapper.dart
@@ -46,8 +46,10 @@ @JS() @anonymous class DartStackTraceUtility { - external factory DartStackTraceUtility( - {StackTraceMapper? mapper, SetSourceMapProvider? setSourceMapProvider}); + external factory DartStackTraceUtility({ + StackTraceMapper? mapper, + SetSourceMapProvider? setSourceMapProvider, + }); } @JS('JSON.stringify') @@ -68,8 +70,12 @@ List toJson() => _bundle.toJson(); @override - SourceMapSpan? spanFor(int line, int column, - {Map<String, SourceFile>? files, String? uri}) { + SourceMapSpan? spanFor( + int line, + int column, { + Map<String, SourceFile>? files, + String? uri, + }) { if (uri == null) { throw ArgumentError.notNull('uri'); } @@ -117,6 +123,7 @@ void main() { // Register with DDC. dartStackTraceUtility = DartStackTraceUtility( - mapper: allowInterop(mapper), - setSourceMapProvider: allowInterop(setSourceMapProvider)); + mapper: allowInterop(mapper), + setSourceMapProvider: allowInterop(setSourceMapProvider), + ); }
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart index 593a662..5322cd1 100644 --- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart +++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -3244,8 +3244,10 @@ /// /// The events are printed in reverse chronological order in case the tail gets /// truncated, the newest events are retained. -String _getEventLog() { +String? _getEventLog() { var initializationEventLog = JS_EMBEDDED_GLOBAL('', INITIALIZATION_EVENT_LOG); + if (initializationEventLog == null) return null; + final o = JS('', 'Array.from(#).reverse()', initializationEventLog); JS( '',
diff --git a/tools/VERSION b/tools/VERSION index d7a9322..e0c8dc0 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 3 MINOR 9 PATCH 0 -PRERELEASE 204 +PRERELEASE 205 PRERELEASE_PATCH 0