diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart index 68033b6f038..f23b510105d 100644 --- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart +++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart @@ -452,6 +452,8 @@ class IncrementalCompiler implements IncrementalKernelGenerator { userCode.uriToSource.remove(debugExprUri); userCode.loader.sourceBytes.remove(debugExprUri); + userCode.runProcedureTransformations(procedure); + return procedure; }); } diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart index e0ef4166758..96b6930aaaf 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart @@ -14,6 +14,7 @@ import 'package:kernel/ast.dart' Class, Constructor, DartType, + Procedure, DynamicType, EmptyStatement, Expression, @@ -28,7 +29,6 @@ import 'package:kernel/ast.dart' Name, NamedExpression, NullLiteral, - Procedure, ProcedureKind, Component, Source, @@ -713,6 +713,12 @@ class KernelTarget extends TargetImplementation { logger: (String msg) => ticker.logMs(msg)); } + void runProcedureTransformations(Procedure procedure) { + backendTarget.performTransformationsOnProcedure( + loader.coreTypes, loader.hierarchy, procedure, + logger: (String msg) => ticker.logMs(msg)); + } + void verify() { errors.addAll(verifyComponent(component)); ticker.logMs("Verified component"); diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart index ec9a8aa5043..1f49bf54a99 100644 --- a/pkg/kernel/lib/target/targets.dart +++ b/pkg/kernel/lib/target/targets.dart @@ -153,6 +153,15 @@ abstract class Target { void performGlobalTransformations(CoreTypes coreTypes, Component component, {void logger(String msg)}); + /// Perform target-specific modular transformations on the given program. + /// + /// This is used when an individual expression is compiled, e.g. for debugging + /// purposes. It is illegal to modify any of the enclosing nodes of the + /// procedure. + void performTransformationsOnProcedure( + CoreTypes coreTypes, ClassHierarchy hierarchy, Procedure procedure, + {void logger(String msg)}) {} + /// Whether a platform library may define a restricted type, such as `bool`, /// `int`, `double`, `num`, and `String`. /// diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart index 322d2c5d4cf..e79a78cea64 100644 --- a/pkg/kernel/lib/target/vm.dart +++ b/pkg/kernel/lib/target/vm.dart @@ -12,7 +12,7 @@ import '../core_types.dart'; import '../transformations/mixin_full_resolution.dart' as transformMixins show transformLibraries; import '../transformations/continuation.dart' as transformAsync - show transformLibraries; + show transformLibraries, transformProcedure; import 'targets.dart'; @@ -74,6 +74,14 @@ class VmTarget extends Target { void performGlobalTransformations(CoreTypes coreTypes, Component component, {void logger(String msg)}) {} + @override + void performTransformationsOnProcedure( + CoreTypes coreTypes, ClassHierarchy hierarchy, Procedure procedure, + {void logger(String msg)}) { + transformAsync.transformProcedure(coreTypes, procedure, flags.syncAsync); + logger?.call("Transformed async functions"); + } + @override Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver, String name, Arguments arguments, int offset, bool isSuper) { diff --git a/runtime/observatory/tests/service/evaluate_async_closure_test.dart b/runtime/observatory/tests/service/evaluate_async_closure_test.dart new file mode 100644 index 00000000000..d01468351c0 --- /dev/null +++ b/runtime/observatory/tests/service/evaluate_async_closure_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// VMOptions=--error_on_bad_type --error_on_bad_override + +import 'dart:async'; + +import 'package:observatory/service_io.dart'; +import 'package:unittest/unittest.dart'; + +import 'test_helper.dart'; + +var tests = [ + (Isolate isolate) async { + // Silence analyzer on 'dart:async' import. + expect(new Future.value(0) != null, isTrue); + String test = "(){ " + " var k = () { return Future.value(3); }; " + " var w = () async { return await k(); }; " + " return w(); " + "}()"; + Library lib = await isolate.rootLibrary.load(); + + var result = await lib.evaluate(test); + expect("$result", equals("Instance(a _Future)")); + }, +]; + +main(args) => runIsolateTests(args, tests);