Run transformations on expression compilation.

Change-Id: Ie0107d908f9e83050e83fbcf1384818100f334b9
Reviewed-on: https://dart-review.googlesource.com/44427
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 68033b6..f23b510 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 @@
       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 e0ef416..96b6930 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 @@
         Class,
         Constructor,
         DartType,
+        Procedure,
         DynamicType,
         EmptyStatement,
         Expression,
@@ -28,7 +29,6 @@
         Name,
         NamedExpression,
         NullLiteral,
-        Procedure,
         ProcedureKind,
         Component,
         Source,
@@ -713,6 +713,12 @@
         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 ec9a8aa..1f49bf5 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -153,6 +153,15 @@
   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 322d2c5..e79a78c 100644
--- a/pkg/kernel/lib/target/vm.dart
+++ b/pkg/kernel/lib/target/vm.dart
@@ -12,7 +12,7 @@
 import '../transformations/mixin_full_resolution.dart' as transformMixins
     show transformLibraries;
 import '../transformations/continuation.dart' as transformAsync
-    show transformLibraries;
+    show transformLibraries, transformProcedure;
 
 import 'targets.dart';
 
@@ -75,6 +75,14 @@
       {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) {
     // See [_InvocationMirror]
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 0000000..d014683
--- /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 = <IsolateTest>[
+  (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);