Infer original expression in SyntheticExpressionJudgment.

Change-Id: I91a27d06ccf4197274fc96597d384ba4e2335dbd
Reviewed-on: https://dart-review.googlesource.com/68426
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index 9113894..0d23da5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -994,30 +994,6 @@
 
   @override
   @failingTest
-  test_prefix_conditionalPropertyAccess_call() async {
-    await super.test_prefix_conditionalPropertyAccess_call();
-  }
-
-  @override
-  @failingTest
-  test_prefix_conditionalPropertyAccess_call_loadLibrary() async {
-    await super.test_prefix_conditionalPropertyAccess_call_loadLibrary();
-  }
-
-  @override
-  @failingTest
-  test_prefix_conditionalPropertyAccess_get() async {
-    await super.test_prefix_conditionalPropertyAccess_get();
-  }
-
-  @override
-  @failingTest
-  test_prefix_conditionalPropertyAccess_get_loadLibrary() async {
-    return super.test_prefix_conditionalPropertyAccess_get_loadLibrary();
-  }
-
-  @override
-  @failingTest
   test_prefix_conditionalPropertyAccess_set() async {
     await super.test_prefix_conditionalPropertyAccess_set();
   }
@@ -1054,12 +1030,6 @@
 
   @override
   @failingTest
-  test_prefixNotFollowedByDot_conditionalMethodInvocation() async {
-    await super.test_prefixNotFollowedByDot_conditionalMethodInvocation();
-  }
-
-  @override
-  @failingTest
   test_privateCollisionInClassTypeAlias_mixinAndMixin() async {
     await super.test_privateCollisionInClassTypeAlias_mixinAndMixin();
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 46e0f32..4ffac65 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -4018,19 +4018,21 @@
       {List<LocatedMessage> context}) {
     // TODO(askesc): Produce explicit error expression wrapping the original.
     // See [issue 29717](https://github.com/dart-lang/sdk/issues/29717)
-    return new SyntheticExpressionJudgment(new Let(
-        new VariableDeclaration.forValue(new SyntheticExpressionJudgment(
-            buildCompileTimeError(
-                message.messageObject, message.charOffset, message.length,
-                context: context)))
-          ..fileOffset = forest.readOffset(expression),
+    return new SyntheticExpressionJudgment(
         new Let(
-            new VariableDeclaration.forValue(expression)
+            new VariableDeclaration.forValue(new SyntheticExpressionJudgment(
+                buildCompileTimeError(
+                    message.messageObject, message.charOffset, message.length,
+                    context: context)))
               ..fileOffset = forest.readOffset(expression),
-            forest.literalNull(null)
+            new Let(
+                new VariableDeclaration.forValue(expression)
+                  ..fileOffset = forest.readOffset(expression),
+                forest.literalNull(null)
+                  ..fileOffset = forest.readOffset(expression))
               ..fileOffset = forest.readOffset(expression))
-          ..fileOffset = forest.readOffset(expression))
-      ..fileOffset = forest.readOffset(expression));
+          ..fileOffset = forest.readOffset(expression),
+        original: expression);
   }
 
   Expression buildFallThroughError(int charOffset) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index bcbb99f..37008fe 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -2797,9 +2797,13 @@
 /// These expressions are removed by type inference and replaced with their
 /// desugared equivalents.
 class SyntheticExpressionJudgment extends Let implements ExpressionJudgment {
+  /// The original expression that is wrapped by this synthetic expression.
+  /// Its type will be inferred.
+  final Expression original;
+
   DartType inferredType;
 
-  SyntheticExpressionJudgment(Expression desugared)
+  SyntheticExpressionJudgment(Expression desugared, {this.original})
       : super(new VariableDeclaration('_', initializer: new NullLiteral()),
             desugared);
 
@@ -2814,6 +2818,9 @@
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
+    if (original != null) {
+      inferrer.inferExpression(original, typeContext, true);
+    }
     _replaceWithDesugared();
     inferredType = const DynamicType();
     return null;
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect b/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
index 01ccbc1..71e52ba 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
@@ -5,7 +5,7 @@
 static method bad() → dynamic {
   for (core::int i = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
+           ^" in let final dynamic #t2 = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
index 01ccbc1..71e52ba 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
@@ -5,7 +5,7 @@
 static method bad() → dynamic {
   for (core::int i = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
+           ^" in let final dynamic #t2 = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
index 689db8c..50d3af2 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
@@ -11,7 +11,7 @@
 static method bad() → dynamic {
   for (core::int i = (let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
+           ^" in let final dynamic #t2 = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
index 7db28e0..0cffebe 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
@@ -11,7 +11,7 @@
 static method bad() → dynamic {
   for (core::int i = (let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
   for (int i = i;; false) {}
-           ^" in let final<BottomType> #t2 = let<BottomType> _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
+           ^" in let final<BottomType> #t2 = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
   }
 }
 static method main() → dynamic {}