Store unresolved variable prefix/postfix operator resolution.

R=brianwilkerson@google.com, paulberry@google.com

Change-Id: If31fa052eb2114ce9fd74d8492957e15e442ef57
Reviewed-on: https://dart-review.googlesource.com/64669
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
index d3605d1..c8bfccf 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
@@ -149,32 +149,6 @@
   test_unresolved_methodInvocation_target_unresolved() async {
     await super.test_unresolved_methodInvocation_target_unresolved();
   }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_unresolved_postfix_operand() async {
-    // Bad state: No data for a at 11
-    await super.test_unresolved_postfix_operand();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_unresolved_postfix_operator() async {
-//    Actual: 'dynamic'
-//    Which: is different.
-//    Expected: A
-    await super.test_unresolved_postfix_operator();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_unresolved_prefix_operand() async {
-    // Bad state: No data for a at 13
-    await super.test_unresolved_prefix_operand();
-  }
 }
 
 /// Tests marked with this annotation fail because of a Fasta problem.
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 104f94f..e79923f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -70,6 +70,7 @@
         Procedure,
         SyntheticExpressionJudgment,
         TypeParameterType,
+        UnresolvedVariableUnaryJudgment,
         VariableDeclaration;
 
 import 'kernel_builder.dart'
@@ -713,25 +714,25 @@
   @override
   Expression buildPrefixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
-    // TODO(ahe): For the Analyzer, we probably need to build a prefix
-    // increment node that wraps an error.
-    return new SyntheticExpressionJudgment(buildError(
+    var error = buildError(
         forest.arguments(
             <Expression>[forest.literalInt(1, null)..fileOffset = offset],
             token),
-        isGetter: true));
+        isGetter: true);
+    return new UnresolvedVariableUnaryJudgment(error, token)
+      ..fileOffset = offset;
   }
 
   @override
   Expression buildPostfixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
-    // TODO(ahe): For the Analyzer, we probably need to build a post increment
-    // node that wraps an error.
-    return new SyntheticExpressionJudgment(buildError(
+    var error = buildError(
         forest.arguments(
             <Expression>[forest.literalInt(1, null)..fileOffset = offset],
             token),
-        isGetter: true));
+        isGetter: true);
+    return new UnresolvedVariableUnaryJudgment(error, token)
+      ..fileOffset = offset;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index 8db8d94..0341daa 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -119,6 +119,7 @@
         UnresolvedTargetInvocationJudgment,
         UnresolvedVariableGetJudgment,
         UnresolvedVariableAssignmentJudgment,
+        UnresolvedVariableUnaryJudgment,
         VariableAssignmentJudgment,
         VariableDeclarationJudgment,
         VariableGetJudgment,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index 7849a99..142237c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -167,9 +167,11 @@
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
     var complexAssignment = startComplexAssignment(value);
     complexAssignment?.isPreIncDec = isPreIncDec;
+    complexAssignment?.isPostIncDec = isPostIncDec;
     var combiner = makeBinary(_makeRead(complexAssignment), binaryOperator,
         interfaceTarget, value, helper,
         offset: offset);
@@ -197,8 +199,12 @@
       bool voidContext: false,
       Procedure interfaceTarget}) {
     if (voidContext) {
-      return buildPrefixIncrement(binaryOperator,
-          offset: offset, voidContext: true, interfaceTarget: interfaceTarget);
+      return buildCompoundAssignment(
+          binaryOperator, forest.literalInt(1, null)..fileOffset = offset,
+          offset: offset,
+          voidContext: voidContext,
+          interfaceTarget: interfaceTarget,
+          isPostIncDec: true);
     }
     var rhs = forest.literalInt(1, null)..fileOffset = offset;
     var complexAssignment = startComplexAssignment(rhs);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
index e08ca25..ce81823 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
@@ -141,7 +141,8 @@
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
     return buildAssignmentError();
   }
 
@@ -266,7 +267,8 @@
       {int offset,
       bool voidContext: false,
       Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
     return unsupported(
         "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
   }
@@ -335,7 +337,8 @@
       {int offset,
       bool voidContext: false,
       Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
     return unsupported(
         "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
   }
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 a929653..de4c780 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
@@ -3565,6 +3565,27 @@
   }
 }
 
+/// Synthetic judgment class representing an attempt to apply a prefix or
+/// postfix operator to an unresolved variable.
+class UnresolvedVariableUnaryJudgment extends SyntheticExpressionJudgment {
+  final Token token;
+
+  UnresolvedVariableUnaryJudgment(kernel.Expression desugared, this.token)
+      : super(desugared);
+
+  @override
+  Expression infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory,
+      DartType typeContext) {
+    inferrer.listener
+        .variableGet(this, token.offset, false, null, const DynamicType());
+    inferrer.listener.variableAssign(
+        this, fileOffset, const DynamicType(), null, null, inferredType);
+    return super.infer(inferrer, factory, typeContext);
+  }
+}
+
 /// Synthetic judgment class representing an attempt to read an unresolved
 /// variable.
 class UnresolvedVariableGetJudgment extends SyntheticExpressionJudgment {