Explicit type args in body_builder

Change-Id: I9f9324b9766a970877c312f429a7873ae2359329
Reviewed-on: https://dart-review.googlesource.com/60428
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
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 503f139..bc647fb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -65,7 +65,8 @@
 
 import '../type_inference/type_inferrer.dart' show TypeInferrer;
 
-import '../type_inference/type_promotion.dart' show TypePromoter;
+import '../type_inference/type_promotion.dart'
+    show TypePromoter, TypePromotionFact, TypePromotionScope;
 
 import 'constness.dart' show Constness;
 
@@ -118,7 +119,7 @@
 const noLocation = null;
 
 abstract class BodyBuilder<Expression, Statement, Arguments>
-    extends ScopeListener<JumpTarget>
+    extends ScopeListener<JumpTarget<Statement>>
     implements ExpressionGeneratorHelper<Expression, Statement, Arguments> {
   // TODO(ahe): Rename [library] to 'part'.
   @override
@@ -293,7 +294,7 @@
 
   @override
   Expression toValue(Object node) {
-    if (node is Generator) {
+    if (node is Generator<Expression, Statement, Arguments>) {
       return node.buildSimpleRead();
     } else if (node is Expression) {
       return node;
@@ -311,7 +312,8 @@
   }
 
   Expression toEffect(Object node) {
-    if (node is Generator) return node.buildForEffect();
+    if (node is Generator<Expression, Statement, Arguments>)
+      return node.buildForEffect();
     return toValue(node);
   }
 
@@ -357,11 +359,11 @@
       switchScope.unclaimedForwardDeclarations
           .forEach((String name, Declaration declaration) {
         if (outerSwitchScope == null) {
-          JumpTarget target = declaration;
-          for (kernel.Statement statement in target.users) {
-            statement.parent.replaceChild(
-                statement,
-                wrapInCompileTimeErrorStatement(statement,
+          JumpTarget<Statement> target = declaration;
+          for (Statement statement in target.users) {
+            toKernelStatement(statement).parent.replaceChild(
+                toKernelStatement(statement),
+                wrapInCompileTimeErrorStatement(toKernelStatement(statement),
                     fasta.templateLabelNotFound.withArguments(name)));
           }
         } else {
@@ -424,7 +426,7 @@
   }
 
   @override
-  JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) {
+  JumpTarget<Statement> createJumpTarget(JumpTargetKind kind, int charOffset) {
     return new JumpTarget<Statement>(
         kind, functionNestingLevel, member, charOffset);
   }
@@ -439,7 +441,7 @@
   @override
   void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
     debugEvent("Metadata");
-    var arguments = pop();
+    Object arguments = pop();
     pushQualifiedReference(beginToken.next, periodBeforeName);
     if (arguments != null) {
       push(arguments);
@@ -449,7 +451,7 @@
     } else {
       String name = pop();
       pop(); // Type arguments (ignored, already reported by parser).
-      var expression = pop();
+      Object expression = pop();
       if (expression is Identifier) {
         Identifier identifier = expression;
         expression = new UnresolvedNameGenerator(
@@ -457,7 +459,7 @@
       }
       if (name?.isNotEmpty ?? false) {
         Token period = periodBeforeName ?? beginToken.next;
-        Generator generator = expression;
+        Generator<Expression, Statement, Arguments> generator = expression;
         expression = generator.buildPropertyAccess(
             new IncompletePropertyAccessGenerator(
                 this, period.next, new Name(name, library.library)),
@@ -466,7 +468,8 @@
       }
 
       ConstantContext savedConstantContext = pop();
-      if (expression is! StaticAccessGenerator) {
+      if (expression
+          is! StaticAccessGenerator<Expression, Statement, Arguments>) {
         push(wrapInCompileTimeError(
             toValue(expression), fasta.messageExpressionNotMetadata));
       } else {
@@ -502,12 +505,12 @@
   void finishFields() {
     debugEvent("finishFields");
     int count = pop();
-    List<FieldBuilder> fields = <FieldBuilder>[];
+    List<FieldBuilder<Object>> fields = <FieldBuilder<Object>>[];
     for (int i = 0; i < count; i++) {
       Expression initializer = pop();
       Identifier identifier = pop();
       String name = identifier.name;
-      FieldBuilder field;
+      FieldBuilder<Object> field;
       if (classBuilder != null) {
         field = classBuilder[name];
       } else {
@@ -530,7 +533,7 @@
       }
     }
     pop(); // Type.
-    List annotations = pop();
+    List<Object> annotations = pop();
     if (annotations != null) {
       _typeInferrer.inferMetadata(this, factory, annotations);
       Field field = fields.first.target;
@@ -566,7 +569,7 @@
   }
 
   void prepareInitializers() {
-    ProcedureBuilder member = this.member;
+    ProcedureBuilder<TypeBuilder> member = this.member;
     scope = member.computeFormalParameterInitializerScope(scope);
     if (member is KernelConstructorBuilder) {
       if (member.isConst &&
@@ -635,19 +638,15 @@
     debugEvent("endInitializer");
     assert(!inInitializer);
     final member = this.member;
-    var node = pop();
+    Object node = pop();
     Initializer initializer;
     if (node is Initializer) {
       initializer = node;
-    } else if (node is Generator) {
+    } else if (node is Generator<Expression, Statement, Arguments>) {
       initializer = node.buildFieldInitializer(initializedFields);
     } else if (node is ConstructorInvocation) {
       initializer = buildSuperInitializer(
-          false,
-          node.target,
-          node.arguments as dynamic, // TODO(ahe): Remove this cast when
-          // buildSuperInitializer is moved to [Forest].
-          token.charOffset);
+          false, node.target, unchecked(node.arguments), token.charOffset);
     } else {
       Expression value = toValue(node);
       if (node is! Throw) {
@@ -676,7 +675,7 @@
 
   @override
   void finishFunction(
-      List annotations,
+      List<Object> annotations,
       FormalParameters<Expression, Statement, Arguments> formals,
       AsyncMarker asyncModifier,
       kernel.Statement body) {
@@ -685,7 +684,7 @@
 
     KernelFunctionBuilder builder = member;
     if (formals?.optional != null) {
-      Iterator<FormalParameterBuilder> formalBuilders =
+      Iterator<FormalParameterBuilder<TypeBuilder>> formalBuilders =
           builder.formals.skip(formals.required.length).iterator;
       for (VariableDeclaration parameter in formals.optional.formals) {
         bool hasMore = formalBuilders.moveNext();
@@ -868,22 +867,23 @@
   @override
   void endArguments(int count, Token beginToken, Token endToken) {
     debugEvent("Arguments");
-    List<dynamic> arguments =
-        new List<dynamic>.filled(count, null, growable: true);
+    List<Object> arguments =
+        new List<Object>.filled(count, null, growable: true);
     popList(count, arguments);
     int firstNamedArgumentIndex = arguments.length;
     for (int i = 0; i < arguments.length; i++) {
-      var node = arguments[i];
+      Object node = arguments[i];
       if (node is NamedExpression) {
         firstNamedArgumentIndex =
             i < firstNamedArgumentIndex ? i : firstNamedArgumentIndex;
       } else {
-        arguments[i] = toValue(node);
+        Expression argument = toValue(node);
+        arguments[i] = argument;
         if (i > firstNamedArgumentIndex) {
           arguments[i] = new NamedExpression(
               "#$i",
               toKernelExpression(deprecated_buildCompileTimeError(
-                  "Expected named argument.", arguments[i].fileOffset)))
+                  "Expected named argument.", forest.readOffset(argument))))
             ..fileOffset = beginToken.charOffset;
         }
       }
@@ -909,7 +909,7 @@
         for (NamedExpression expression in named) {
           if (seenNames.containsKey(expression.name)) {
             hasProblem = true;
-            var prevNamedExpression = seenNames[expression.name];
+            NamedExpression prevNamedExpression = seenNames[expression.name];
             prevNamedExpression.value = toKernelExpression(
                 deprecated_buildCompileTimeError(
                     "Duplicated named argument '${expression.name}'.",
@@ -973,7 +973,7 @@
 
   @override
   finishSend(Object receiver, Arguments arguments, int charOffset) {
-    if (receiver is Generator) {
+    if (receiver is Generator<Expression, Statement, Arguments>) {
       return receiver.doInvocation(charOffset, arguments);
     } else {
       return buildMethodInvocation(
@@ -1046,7 +1046,7 @@
     if (optional("??", token)) return doIfNull(token);
     if (optional("?.", token)) return doIfNotNull(token);
     Expression argument = popForValue();
-    var receiver = pop();
+    Object receiver = pop();
     bool isSuper = false;
     if (receiver is ThisAccessGenerator && receiver.isSuper) {
       ThisAccessGenerator thisAccessorReceiver = receiver;
@@ -1108,7 +1108,7 @@
 
   /// Handle `a?.b(...)`.
   void doIfNotNull(Token token) {
-    var send = pop();
+    Object send = pop();
     if (send is IncompleteSendGenerator) {
       push(send.withReceiver(pop(), token.charOffset, isNullAware: true));
     } else {
@@ -1121,7 +1121,7 @@
   }
 
   void doDotOrCascadeExpression(Token token) {
-    var send = pop();
+    Object send = pop();
     if (send is IncompleteSendGenerator) {
       Object receiver = optional(".", token) ? pop() : popForValue();
       push(send.withReceiver(receiver, token.charOffset));
@@ -1328,15 +1328,16 @@
     /// Performs a similar lookup to [lookupConstructor], but using a slower
     /// implementation.
     Constructor lookupConstructorWithPatches(Name name, bool isSuper) {
-      ClassBuilder builder = classBuilder.origin;
+      ClassBuilder<TypeBuilder, Object> builder = classBuilder.origin;
 
-      ClassBuilder getSuperclass(ClassBuilder builder) {
+      ClassBuilder<TypeBuilder, Object> getSuperclass(
+          ClassBuilder<TypeBuilder, Object> builder) {
         // This way of computing the superclass is slower than using the kernel
         // objects directly.
-        var supertype = builder.supertype;
-        if (supertype is NamedTypeBuilder) {
-          var builder = supertype.declaration;
-          if (builder is ClassBuilder) return builder;
+        Object supertype = builder.supertype;
+        if (supertype is NamedTypeBuilder<TypeBuilder, Object>) {
+          Object builder = supertype.declaration;
+          if (builder is ClassBuilder<TypeBuilder, Object>) return builder;
         }
         return null;
       }
@@ -1457,9 +1458,9 @@
       // [ProcedureBuilder.computeFormalParameterInitializerScope]. If that
       // wasn't the case, we could always use [VariableUseGenerator].
       if (declaration.isFinal) {
-        var fact = typePromoter.getFactForAccess(
+        Object fact = typePromoter.getFactForAccess(
             declaration.target, functionNestingLevel);
-        var scope = typePromoter.currentScope;
+        Object scope = typePromoter.currentScope;
         return new ReadOnlyAccessGenerator<Expression, Statement, Arguments>(
             this,
             token,
@@ -1550,7 +1551,7 @@
   void handleQualified(Token period) {
     debugEvent("Qualified");
     Identifier name = pop();
-    var receiver = pop();
+    Object receiver = pop();
     push([receiver, name]);
   }
 
@@ -1574,7 +1575,7 @@
       String value = unescapeString(token.lexeme, token, this);
       push(forest.literalString(value, token));
     } else {
-      var count = 1 + interpolationCount * 2;
+      Object count = 1 + interpolationCount * 2;
       List<Object> parts =
           popList(count, new List<Object>.filled(count, null, growable: true));
       Token first = parts.first;
@@ -1590,7 +1591,7 @@
         }
       }
       for (int i = 1; i < parts.length - 1; i++) {
-        var part = parts[i];
+        Object part = parts[i];
         if (part is Token) {
           if (part.lexeme.length != 0) {
             String value = unescape(part.lexeme, quote, part, this);
@@ -1845,8 +1846,8 @@
   void handleAssignmentExpression(Token token) {
     debugEvent("AssignmentExpression");
     Expression value = popForValue();
-    var generator = pop();
-    if (generator is! Generator) {
+    Object generator = pop();
+    if (generator is! Generator<Expression, Statement, Arguments>) {
       push(buildCompileTimeError(fasta.messageNotAnLvalue,
           offsetForToken(token), lengthForToken(token)));
     } else {
@@ -1857,8 +1858,8 @@
 
   @override
   void enterLoop(int charOffset) {
-    if (peek() is LabelTarget) {
-      LabelTarget target = peek();
+    if (peek() is LabelTarget<Statement>) {
+      LabelTarget<Statement> target = peek();
       enterBreakTarget(charOffset, target.breakTarget);
       enterContinueTarget(charOffset, target.continueTarget);
     } else {
@@ -1877,7 +1878,7 @@
   }
 
   List<VariableDeclaration> buildVariableDeclarations(variableOrExpression) {
-    if (variableOrExpression is Generator) {
+    if (variableOrExpression is Generator<Expression, Statement, Arguments>) {
       variableOrExpression = variableOrExpression.buildForEffect();
     }
     if (variableOrExpression is VariableDeclaration) {
@@ -1893,9 +1894,9 @@
     } else if (forest.isVariablesDeclaration(variableOrExpression)) {
       return forest
           .variablesDeclarationExtractDeclarations(variableOrExpression);
-    } else if (variableOrExpression is List) {
+    } else if (variableOrExpression is List<Object>) {
       List<VariableDeclaration> variables = <VariableDeclaration>[];
-      for (var v in variableOrExpression) {
+      for (Object v in variableOrExpression) {
         variables.addAll(buildVariableDeclarations(v));
       }
       return variables;
@@ -1912,7 +1913,7 @@
     Statement body = popStatement();
     List<Expression> updates = popListForEffect(updateExpressionCount);
     Statement conditionStatement = popStatement();
-    dynamic variableOrExpression = pop();
+    Object variableOrExpression = pop();
     List<VariableDeclaration> variables =
         buildVariableDeclarations(variableOrExpression);
     if (variables == null) {
@@ -1920,8 +1921,8 @@
           forKeyword.charOffset, uri);
     }
     exitLocalScope();
-    JumpTarget continueTarget = exitContinueTarget();
-    JumpTarget breakTarget = exitBreakTarget();
+    JumpTarget<Statement> continueTarget = exitContinueTarget();
+    JumpTarget<Statement> breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
       body = forest.syntheticLabeledStatement(body);
       continueTarget.resolveContinues(forest, body);
@@ -2018,7 +2019,7 @@
   void handleLiteralMap(
       int count, Token leftBrace, Token constKeyword, Token rightBrace) {
     debugEvent("LiteralMap");
-    List entries = forest.mapEntryList(count);
+    List<Object> entries = forest.mapEntryList(count);
     popList(count, entries);
     Object typeArguments = pop();
     DartType keyType;
@@ -2092,13 +2093,14 @@
     // TODO(ahe): The scope is wrong for return types of generic functions.
     debugEvent("Type");
     List<DartType> arguments = pop();
-    dynamic name = pop();
-    if (name is List) {
-      if (name.length != 2) {
-        unexpected("${name.length}", "2", beginToken.charOffset, uri);
+    Object name = pop();
+    if (name is List<Object>) {
+      List<Object> list = name;
+      if (list.length != 2) {
+        unexpected("${list.length}", "2", beginToken.charOffset, uri);
       }
-      var prefix = name[0];
-      Identifier suffix = name[1];
+      Object prefix = list[0];
+      Identifier suffix = list[1];
       if (prefix is PrefixBuilder) {
         name = scopeLookup(prefix.exportScope, suffix.name, beginToken,
             isQualified: true, prefix: prefix);
@@ -2114,7 +2116,7 @@
         return;
       }
     }
-    if (name is Generator) {
+    if (name is Generator<Expression, Statement, Arguments>) {
       push(name.buildTypeWithBuiltArguments(arguments));
     } else if (name is TypeBuilder) {
       push(name.build(library));
@@ -2134,7 +2136,7 @@
     debugEvent("beginFunctionType");
   }
 
-  void enterFunctionTypeScope(List typeVariables) {
+  void enterFunctionTypeScope(List<Object> typeVariables) {
     debugEvent("enterFunctionTypeScope");
     enterLocalScope(null,
         scope.createNestedScope("function-type scope", isModifiable: true));
@@ -2276,7 +2278,7 @@
     if (!inCatchClause &&
         functionNestingLevel == 0 &&
         memberKind != MemberKind.GeneralizedFunctionType) {
-      ProcedureBuilder member = this.member;
+      ProcedureBuilder<TypeBuilder> member = this.member;
       KernelFormalParameterBuilder formal = member.getFormal(name.name);
       if (formal == null) {
         internalProblem(
@@ -2318,7 +2320,7 @@
     FormalParameterKind kind = optional("{", beginToken)
         ? FormalParameterKind.optionalNamed
         : FormalParameterKind.optionalPositional;
-    var variables =
+    Object variables =
         new List<VariableDeclaration>.filled(count, null, growable: true);
     popList(count, variables);
     push(new OptionalFormals(kind, variables));
@@ -2354,7 +2356,7 @@
   @override
   void endFormalParameterDefaultValueExpression() {
     debugEvent("FormalParameterDefaultValueExpression");
-    var defaultValueExpression = pop();
+    Object defaultValueExpression = pop();
     constantContext = pop();
     push(defaultValueExpression);
   }
@@ -2391,8 +2393,9 @@
     List<VariableDeclaration> variables =
         new List<VariableDeclaration>.filled(count, null, growable: true);
     popList(count, variables);
-    var formals = new FormalParameters<Expression, Statement, Arguments>(
-        variables, optional, beginToken.charOffset);
+    FormalParameters<Expression, Statement, Arguments> formals =
+        new FormalParameters<Expression, Statement, Arguments>(
+            variables, optional, beginToken.charOffset);
     constantContext = pop();
     push(formals);
     if ((inCatchClause || functionNestingLevel != 0) &&
@@ -2483,7 +2486,7 @@
       Token openSquareBracket, Token closeSquareBracket) {
     debugEvent("IndexedExpression");
     Expression index = popForValue();
-    var receiver = pop();
+    Object receiver = pop();
     if (receiver is ThisAccessGenerator && receiver.isSuper) {
       push(new SuperIndexedAccessGenerator<Expression, Statement, Arguments>(
           this,
@@ -2500,7 +2503,7 @@
   @override
   void handleUnaryPrefixExpression(Token token) {
     debugEvent("UnaryPrefixExpression");
-    var receiver = pop();
+    Object receiver = pop();
     if (optional("!", token)) {
       push(forest.notExpression(toValue(receiver), token));
     } else {
@@ -2544,8 +2547,8 @@
   @override
   void handleUnaryPrefixAssignmentExpression(Token token) {
     debugEvent("UnaryPrefixAssignmentExpression");
-    var generator = pop();
-    if (generator is Generator) {
+    Object generator = pop();
+    if (generator is Generator<Expression, Statement, Arguments>) {
       push(generator.buildPrefixIncrement(incrementOperator(token),
           offset: token.charOffset));
     } else {
@@ -2557,8 +2560,8 @@
   @override
   void handleUnaryPostfixAssignmentExpression(Token token) {
     debugEvent("UnaryPostfixAssignmentExpression");
-    var generator = pop();
-    if (generator is Generator) {
+    Object generator = pop();
+    if (generator is Generator<Expression, Statement, Arguments>) {
       push(new DelayedPostfixIncrement(
           this, token, generator, incrementOperator(token), null));
     } else {
@@ -2611,10 +2614,11 @@
     Identifier suffix = popIfNotNull(periodBeforeName);
     Identifier identifier;
     List<DartType> typeArguments = pop();
-    dynamic type = pop();
-    if (type is List) {
-      var prefix = type[0];
-      identifier = type[1];
+    Object type = pop();
+    if (type is List<Object>) {
+      List<Object> list = type;
+      Object prefix = list[0];
+      identifier = list[1];
       if (prefix is PrefixBuilder) {
         type = scopeLookup(
             prefix.exportScope, identifier.name, identifier.token,
@@ -2622,7 +2626,7 @@
         identifier = null;
       } else if (prefix is TypeUseGenerator<Expression, Statement, Arguments>) {
         type = prefix;
-      } else if (prefix is Generator) {
+      } else if (prefix is Generator<Expression, Statement, Arguments>) {
         String name = suffix == null
             ? "${prefix.plainNameForRead}.${identifier.name}"
             : "${prefix.plainNameForRead}.${identifier.name}.$suffix";
@@ -2724,7 +2728,7 @@
               forest.argumentsPositional(arguments).length)
           .withLocation(uri, offset, noLength);
     }
-    List named = forest.argumentsNamed(arguments);
+    List<Object> named = forest.argumentsNamed(arguments);
     if (named.isNotEmpty) {
       Set<String> names =
           new Set.from(function.namedParameters.map((a) => a.name));
@@ -2737,7 +2741,7 @@
       }
     }
 
-    List types = forest.argumentsTypeArguments(arguments);
+    List<Object> types = forest.argumentsTypeArguments(arguments);
     if (typeParameters.length != types.length) {
       // TODO(paulberry): Report error in this case as well,
       // after https://github.com/dart-lang/sdk/issues/32130 is fixed.
@@ -2767,7 +2771,7 @@
               forest.argumentsPositional(arguments).length)
           .withLocation(uri, offset, noLength);
     }
-    List named = forest.argumentsNamed(arguments);
+    List<Object> named = forest.argumentsNamed(arguments);
     if (named.isNotEmpty) {
       Set<String> names =
           new Set.from(function.namedParameters.map((a) => a.name));
@@ -2817,7 +2821,7 @@
   @override
   void endConstLiteral(Token token) {
     debugEvent("endConstLiteral");
-    var literal = pop();
+    Object literal = pop();
     constantContext = pop();
     push(literal);
   }
@@ -2835,7 +2839,7 @@
     String name = pop();
     List<DartType> typeArguments = pop();
 
-    var type = pop();
+    Object type = pop();
     PrefixBuilder deferredPrefix;
     int checkOffset;
     if (type is DeferredAccessGenerator<Expression, Statement, Arguments>) {
@@ -2855,7 +2859,7 @@
     }
 
     ConstantContext savedConstantContext = pop();
-    if (type is TypeDeclarationBuilder) {
+    if (type is TypeDeclarationBuilder<TypeBuilder, Object>) {
       Expression expression = buildConstructorInvocation(
           type, nameToken, arguments, name, typeArguments, offset, constness);
       push(deferredPrefix != null
@@ -2880,7 +2884,7 @@
 
   @override
   Expression buildConstructorInvocation(
-      TypeDeclarationBuilder type,
+      TypeDeclarationBuilder<TypeBuilder, Object> type,
       Token nameToken,
       Arguments arguments,
       String name,
@@ -2898,8 +2902,8 @@
     }
 
     String errorName;
-    if (type is ClassBuilder) {
-      if (type is EnumBuilder) {
+    if (type is ClassBuilder<TypeBuilder, Object>) {
+      if (type is EnumBuilder<TypeBuilder, Object>) {
         return deprecated_buildCompileTimeError(
             "An enum class can't be instantiated.", nameToken.charOffset);
       }
@@ -3057,7 +3061,7 @@
     functionNestingLevel--;
     inCatchBlock = pop();
     switchScope = pop();
-    List typeVariables = pop();
+    List<Object> typeVariables = pop();
     exitLocalScope();
     push(typeVariables ?? NullValue.TypeVariables);
   }
@@ -3071,7 +3075,7 @@
   @override
   void beginNamedFunctionExpression(Token token) {
     debugEvent("beginNamedFunctionExpression");
-    List typeVariables = pop();
+    List<Object> typeVariables = pop();
     // Create an additional scope in which the named function expression is
     // declared.
     enterLocalScope("named function");
@@ -3090,9 +3094,9 @@
     AsyncMarker asyncModifier = pop();
     exitLocalScope();
     FormalParameters<Expression, Statement, Arguments> formals = pop();
-    var declaration = pop();
-    var returnType = pop();
-    var hasImplicitReturnType = returnType == null;
+    Object declaration = pop();
+    Object returnType = pop();
+    Object hasImplicitReturnType = returnType == null;
     returnType ??= const DynamicType();
     exitFunction();
     List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
@@ -3210,8 +3214,8 @@
     debugEvent("DoWhileStatement");
     Expression condition = popForValue();
     Statement body = popStatement();
-    JumpTarget continueTarget = exitContinueTarget();
-    JumpTarget breakTarget = exitBreakTarget();
+    JumpTarget<Statement> continueTarget = exitContinueTarget();
+    JumpTarget<Statement> breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
       body = forest.syntheticLabeledStatement(body);
       continueTarget.resolveContinues(forest, body);
@@ -3244,14 +3248,14 @@
     debugEvent("ForIn");
     Statement body = popStatement();
     Expression expression = popForValue();
-    var lvalue = pop();
+    Object lvalue = pop();
     exitLocalScope();
-    JumpTarget continueTarget = exitContinueTarget();
-    JumpTarget breakTarget = exitBreakTarget();
+    JumpTarget<Statement> continueTarget = exitContinueTarget();
+    JumpTarget<Statement> breakTarget = exitBreakTarget();
     kernel.Statement kernelBody = toKernelStatement(body);
     if (continueTarget.hasUsers) {
       kernelBody = new ShadowLabeledStatement(kernelBody);
-      continueTarget.resolveContinues(forest, kernelBody);
+      continueTarget.resolveContinues(forest, toStatement(kernelBody));
     }
     VariableDeclaration variable;
     bool declaresVariable = false;
@@ -3263,7 +3267,7 @@
         deprecated_addCompileTimeError(
             variable.fileOffset, "A for-in loop-variable can't be 'const'.");
       }
-    } else if (lvalue is Generator) {
+    } else if (lvalue is Generator<Expression, Statement, Arguments>) {
       /// We are in this case, where `lvalue` isn't a [VariableDeclaration]:
       ///
       ///     for (lvalue in expression) body
@@ -3276,12 +3280,13 @@
       ///     }
       variable =
           new ShadowVariableDeclaration.forValue(null, functionNestingLevel);
-      var fact = typePromoter.getFactForAccess(variable, functionNestingLevel);
-      var scope = typePromoter.currentScope;
-      syntheticAssignment = lvalue.buildAssignment(
-          new ShadowVariableGet(variable, fact, scope)
-            ..fileOffset = inKeyword.offset,
-          voidContext: true);
+      TypePromotionFact fact =
+          typePromoter.getFactForAccess(variable, functionNestingLevel);
+      TypePromotionScope scope = typePromoter.currentScope;
+      syntheticAssignment = toKernelExpression(lvalue.buildAssignment(
+          toExpression(new ShadowVariableGet(variable, fact, scope)
+            ..fileOffset = inKeyword.offset),
+          voidContext: true));
       kernelBody = combineStatements(
           new ShadowLoopAssignmentStatement(syntheticAssignment), kernelBody);
     } else {
@@ -3304,7 +3309,7 @@
       ..bodyOffset = kernelBody.fileOffset;
     if (breakTarget.hasUsers) {
       result = new ShadowLabeledStatement(result);
-      breakTarget.resolveBreaks(forest, result);
+      breakTarget.resolveBreaks(forest, toStatement(result));
     }
     exitLoopOrSwitch(toStatement(result));
   }
@@ -3323,7 +3328,7 @@
         new List<Object>.filled(labelCount, null, growable: true);
     popList(labelCount, labels);
     enterLocalScope(null, scope.createNestedLabelScope());
-    LabelTarget target = new LabelTarget<Statement>(
+    LabelTarget<Statement> target = new LabelTarget<Statement>(
         labels, member, functionNestingLevel, token.charOffset);
     for (Object label in labels) {
       scope.declareLabel(forest.getLabelName(label), target);
@@ -3335,7 +3340,7 @@
   void endLabeledStatement(int labelCount) {
     debugEvent("LabeledStatement");
     Statement statement = popStatement();
-    LabelTarget target = pop();
+    LabelTarget<Statement> target = pop();
     exitLocalScope();
     if (target.breakTarget.hasUsers) {
       if (statement is! LabeledStatement) {
@@ -3376,8 +3381,8 @@
     debugEvent("WhileStatement");
     Statement body = popStatement();
     Expression condition = popForValue();
-    JumpTarget continueTarget = exitContinueTarget();
-    JumpTarget breakTarget = exitBreakTarget();
+    JumpTarget<Statement> continueTarget = exitContinueTarget();
+    JumpTarget<Statement> breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
       body = forest.syntheticLabeledStatement(body);
       continueTarget.resolveContinues(forest, body);
@@ -3449,13 +3454,13 @@
   @override
   void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
     debugEvent("beginSwitchCase");
-    var count = labelCount + expressionCount;
+    Object count = labelCount + expressionCount;
     List<Object> labelsAndExpressions =
         popList(count, new List<Object>.filled(count, null, growable: true));
     List<Object> labels = <Object>[];
     List<Expression> expressions = <Expression>[];
     if (labelsAndExpressions != null) {
-      for (var labelOrExpression in labelsAndExpressions) {
+      for (Object labelOrExpression in labelsAndExpressions) {
         if (forest.isLabel(labelOrExpression)) {
           labels.add(labelOrExpression);
         } else {
@@ -3517,7 +3522,7 @@
     debugEvent("SwitchStatement");
 
     List<SwitchCase> cases = pop();
-    JumpTarget target = exitBreakTarget();
+    JumpTarget<Statement> target = exitBreakTarget();
     exitSwitchScope();
     exitLocalScope();
     Expression expression = popForValue();
@@ -3526,7 +3531,7 @@
           ..fileOffset = switchKeyword.charOffset;
     if (target.hasUsers) {
       result = new ShadowLabeledStatement(result);
-      target.resolveBreaks(forest, result);
+      target.resolveBreaks(forest, toStatement(result));
     }
     exitLoopOrSwitch(toStatement(result));
   }
@@ -3540,7 +3545,8 @@
       List<Object> labels = pop();
       SwitchCase current = cases[i] = pop();
       for (Object label in labels) {
-        JumpTarget target = switchScope.lookupLabel(forest.getLabelName(label));
+        JumpTarget<Statement> target =
+            switchScope.lookupLabel(forest.getLabelName(label));
         if (target != null) {
           target.resolveGotos(forest, current);
         }
@@ -3585,7 +3591,7 @@
   void handleBreakStatement(
       bool hasTarget, Token breakKeyword, Token endToken) {
     debugEvent("BreakStatement");
-    var target = breakTarget;
+    JumpTarget<Statement> target = breakTarget;
     Identifier identifier;
     String name;
     if (hasTarget) {
@@ -3598,7 +3604,7 @@
           deprecated_buildCompileTimeErrorStatement(
               "No target of break.", breakKeyword.charOffset));
     } else if (target == null ||
-        target is! JumpTarget ||
+        target is! JumpTarget<Statement> ||
         !target.isBreakTarget) {
       push(compileTimeErrorInLoopOrSwitch =
           deprecated_buildCompileTimeErrorStatement(
@@ -3620,20 +3626,21 @@
   void handleContinueStatement(
       bool hasTarget, Token continueKeyword, Token endToken) {
     debugEvent("ContinueStatement");
-    var target = continueTarget;
+    JumpTarget<Statement> target = continueTarget;
     Identifier identifier;
     String name;
     if (hasTarget) {
       identifier = pop();
       name = identifier.name;
-      target = scope.lookupLabel(identifier.name);
-      if (target != null && target is! JumpTarget) {
+      Declaration namedTarget = scope.lookupLabel(identifier.name);
+      if (namedTarget != null && namedTarget is! JumpTarget<Statement>) {
         push(compileTimeErrorInLoopOrSwitch =
             deprecated_buildCompileTimeErrorStatement(
                 "Target of continue must be a label.",
                 continueKeyword.charOffset));
         return;
       }
+      target = namedTarget;
       if (target == null) {
         if (switchScope == null) {
           push(deprecated_buildCompileTimeErrorStatement(
@@ -3648,7 +3655,7 @@
         ContinueSwitchStatement statement =
             new ShadowContinueSwitchStatement(null)
               ..fileOffset = continueKeyword.charOffset;
-        target.addGoto(statement);
+        target.addGoto(toStatement(statement));
         push(statement);
         return;
       }
@@ -3693,7 +3700,7 @@
     // TODO(dmitryas):  Move the resolution to the appropriate place once
     // [ClassMemberParser] is not used to build the type variables for the local
     // function.  See the comment above.
-    for (UnresolvedType t in library.types) {
+    for (UnresolvedType<TypeBuilder> t in library.types) {
       t.resolveIn(scope, library);
     }
     library.types.clear();
@@ -3775,7 +3782,8 @@
     push(typeVariables ?? NullValue.TypeVariables);
   }
 
-  List<TypeParameter> typeVariableBuildersToKernel(List typeVariableBuilders) {
+  List<TypeParameter> typeVariableBuildersToKernel(
+      List<Object> typeVariableBuilders) {
     if (typeVariableBuilders == null) return null;
     List<TypeParameter> typeParameters = new List<TypeParameter>.filled(
         typeVariableBuilders.length, null,
@@ -4230,7 +4238,7 @@
   @override
   Expression wrapInDeferredCheck(
       Expression expression, KernelPrefixBuilder prefix, int charOffset) {
-    var check = new VariableDeclaration.forValue(
+    Object check = new VariableDeclaration.forValue(
         toKernelExpression(forest.checkLibraryIsLoaded(prefix.dependency)))
       ..fileOffset = charOffset;
     return toExpression(
@@ -4240,33 +4248,33 @@
   // TODO(ahe): Remove this method once Forest API is complete.
   @override
   T storeOffset<T>(T object, int offset) {
-    TreeNode node = object as dynamic;
+    TreeNode node = unchecked(object);
     node.fileOffset = offset;
     return object;
   }
 
   // TODO(ahe): Remove this method once Forest API is complete.
   kernel.Expression toKernelExpression(Expression expression) {
-    return expression as dynamic;
+    return unchecked(expression);
   }
 
   // TODO(ahe): Remove this method once Forest API is complete.
   Expression toExpression(kernel.Expression expression) {
-    return expression as dynamic;
+    return unchecked(expression);
   }
 
   List<kernel.Expression> toKernelExpressionList(List<Expression> expressions) {
-    return expressions as dynamic;
+    return unchecked(expressions);
   }
 
   // TODO(ahe): Remove this method once Forest API is complete.
   kernel.Statement toKernelStatement(Statement statement) {
-    return statement as dynamic;
+    return unchecked(statement);
   }
 
   // TODO(ahe): Remove this method once Forest API is complete.
   Statement toStatement(kernel.Statement statement) {
-    return statement as dynamic;
+    return unchecked(statement);
   }
 
   /// TODO(ahe): This method is temporarily implemented by subclasses. Once type
@@ -4352,7 +4360,7 @@
   }
 
   void resolveBreaks(
-      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+      Forest<Object, Statement, Object, Object> forest, Statement target) {
     assert(isBreakTarget);
     for (Statement user in users) {
       forest.resolveBreak(target, user);
@@ -4361,7 +4369,7 @@
   }
 
   void resolveContinues(
-      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+      Forest<Object, Statement, Object, Object> forest, Statement target) {
     assert(isContinueTarget);
     for (Statement user in users) {
       forest.resolveContinue(target, user);
@@ -4370,7 +4378,7 @@
   }
 
   void resolveGotos(
-      Forest<dynamic, Statement, dynamic, dynamic> forest, Object target) {
+      Forest<Object, Statement, Object, Object> forest, Object target) {
     assert(isGotoTarget);
     for (Statement user in users) {
       forest.resolveContinueInSwitch(target, user);
@@ -4389,9 +4397,9 @@
   @override
   final MemberBuilder parent;
 
-  final JumpTarget breakTarget;
+  final JumpTarget<Statement> breakTarget;
 
-  final JumpTarget continueTarget;
+  final JumpTarget<Statement> continueTarget;
 
   final int functionNestingLevel;
 
@@ -4433,17 +4441,17 @@
   }
 
   void resolveBreaks(
-      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+      Forest<Object, Statement, Object, Object> forest, Statement target) {
     breakTarget.resolveBreaks(forest, target);
   }
 
   void resolveContinues(
-      Forest<dynamic, Statement, dynamic, dynamic> forest, Statement target) {
+      Forest<Object, Statement, Object, Object> forest, Statement target) {
     continueTarget.resolveContinues(forest, target);
   }
 
   void resolveGotos(
-      Forest<dynamic, Statement, dynamic, dynamic> forest, Object target) {
+      Forest<Object, Statement, Object, Object> forest, Object target) {
     unsupported("resolveGotos", charOffset, fileUri);
   }
 
@@ -4511,7 +4519,7 @@
   }
 
   Scope computeFormalParameterScope(Scope parent, Declaration declaration,
-      ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper) {
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper) {
     if (required.length == 0 && optional == null) return parent;
     Map<String, Declaration> local = <String, Declaration>{};
 
@@ -4567,7 +4575,7 @@
     return node.fullNameForErrors;
   } else if (node is ThisAccessGenerator) {
     return node.isSuper ? "super" : "this";
-  } else if (node is Generator) {
+  } else if (node is Generator<Object, Object, Object>) {
     return node.plainNameForRead;
   } else {
     return unhandled("${node.runtimeType}", "getNodeName", -1, null);
@@ -4594,3 +4602,6 @@
         asyncToken.charOffset, null);
   }
 }
+
+// TODO(ahe): Remove this method when all AST nodes have moved to [Forest].
+dynamic unchecked(Object o) => o;
diff --git a/pkg/front_end/lib/src/fasta/rewrite_severity.dart b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
index 9298669..0455195 100644
--- a/pkg/front_end/lib/src/fasta/rewrite_severity.dart
+++ b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
@@ -76,7 +76,6 @@
       case "fasta_codes.dart":
       case "import.dart":
       case "incremental_compiler.dart":
-      case "kernel/body_builder.dart":
       case "kernel/expression_generator.dart":
       case "kernel/expression_generator_helper.dart":
       case "kernel/fangorn.dart":