Resolve invalid 'as' constant expression.

Change-Id: I4d9463fe60a47ec2dc44d5da30d4923b20244e45
Reviewed-on: https://dart-review.googlesource.com/68428
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/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 742ecd8..8eb13a5 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -3516,6 +3516,23 @@
         useCFE || Parser.useFasta ? 'StackTrace' : 'dynamic');
   }
 
+  test_invalid_const_as() async {
+    addTestFile(r'''
+class A {
+  final int a;
+  const A(num b) : a = b as int;
+}
+''');
+    await resolveTestFile();
+    expect(result.errors, isNotEmpty);
+
+    var bRef = findNode.simple('b as int');
+    assertElement(bRef, findElement.parameter('b'));
+    assertType(bRef, 'num');
+
+    assertTypeName(findNode.typeName('int;'), intElement, 'int');
+  }
+
   test_invalid_const_constructor_initializer_field_multiple() async {
     addTestFile(r'''
 var a = 0;
@@ -10212,20 +10229,17 @@
     }
 
     for (var accessor in unitElement.accessors) {
-      for (var parameter in accessor.parameters) {
-        considerParameter(parameter);
-      }
+      accessor.parameters.forEach(considerParameter);
     }
     for (var function in unitElement.functions) {
-      for (var parameter in function.parameters) {
-        considerParameter(parameter);
-      }
+      function.parameters.forEach(considerParameter);
     }
     for (var class_ in unitElement.types) {
+      for (var constructor in class_.constructors) {
+        constructor.parameters.forEach(considerParameter);
+      }
       for (var method in class_.methods) {
-        for (var parameter in method.parameters) {
-          considerParameter(parameter);
-        }
+        method.parameters.forEach(considerParameter);
       }
     }
     if (parameterElement != null) {
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 4ffac65..0429009 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2280,14 +2280,15 @@
     debugEvent("AsOperator");
     DartType type = pop();
     Expression expression = popForValue();
+    Expression error;
     if (constantContext != ConstantContext.none) {
-      push(buildCompileTimeError(
+      error = buildCompileTimeError(
           fasta.templateNotConstantExpression.withArguments('As expression'),
           operator.charOffset,
-          operator.length));
-    } else {
-      push(forest.asExpression(expression, type, operator));
+          operator.length);
     }
+    push(
+        forest.asExpression(expression, type, operator, desugaredError: error));
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 9e5ec5e..caaeeed 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -288,9 +288,11 @@
   }
 
   @override
-  Expression asExpression(Expression expression, covariant type, Token token) {
+  Expression asExpression(Expression expression, covariant type, Token token,
+      {Expression desugaredError}) {
     return new AsJudgment(
-        expression, typeInferenceTokensSaver?.asExpressionTokens(token), type)
+        expression, typeInferenceTokensSaver?.asExpressionTokens(token), type,
+        desugaredError: desugaredError)
       ..fileOffset = offsetForToken(token);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 5b4ee73..f795d06 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -162,8 +162,8 @@
 
   Expression checkLibraryIsLoaded(covariant dependency);
 
-  Expression asExpression(
-      Expression expression, covariant type, Token location);
+  Expression asExpression(Expression expression, covariant type, Token location,
+      {Expression desugaredError});
 
   /// Return a representation of an assert that appears in a constructor's
   /// initializer list.
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 37008fe..9d86807 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
@@ -203,10 +203,12 @@
 /// Shadow object for [AsExpression].
 class AsJudgment extends AsExpression implements ExpressionJudgment {
   final AsExpressionTokens tokens;
+  final Expression desugaredError;
 
   DartType inferredType;
 
-  AsJudgment(Expression operand, this.tokens, DartType type)
+  AsJudgment(Expression operand, this.tokens, DartType type,
+      {this.desugaredError})
       : super(operand, type);
 
   ExpressionJudgment get judgment => operand;
@@ -218,6 +220,10 @@
     inferredType = type;
     inferrer.listener
         .asExpression(this, fileOffset, null, tokens, null, inferredType);
+    if (desugaredError != null) {
+      parent.replaceChild(this, desugaredError);
+      parent = null;
+    }
     return null;
   }
 }