[fasta] Add more nodes to the Forest API

Change-Id: I8fa411533a2458cb099fd424b47d3fca8a2a4aad
Reviewed-on: https://dart-review.googlesource.com/53660
Reviewed-by: Peter von der Ahé <ahe@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@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 c477cfd..7bfd429 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -942,8 +942,7 @@
     if (receiver is ThisAccessor && receiver.isSuper) {
       ThisAccessor thisAccessorReceiver = receiver;
       isSuper = true;
-      receiver = new ShadowThisExpression()
-        ..fileOffset = offsetForToken(thisAccessorReceiver.token);
+      receiver = forest.thisExpression(thisAccessorReceiver.token);
     }
     push(buildBinaryOperator(toValue(receiver), token, argument, isSuper));
   }
@@ -966,7 +965,7 @@
           // evaluating [a] and [b].
           isConstantExpression: !isSuper,
           isSuper: isSuper);
-      return negate ? new ShadowNot(result) : result;
+      return negate ? forest.notExpression(result, null) : result;
     }
   }
 
@@ -1470,8 +1469,7 @@
           expressions.add(forest.literalString(value, last));
         }
       }
-      push(new ShadowStringConcatenation(expressions)
-        ..fileOffset = offsetForToken(endToken));
+      push(forest.stringConcatenationExpression(expressions, endToken));
     }
   }
 
@@ -1507,7 +1505,7 @@
         }
       }
     }
-    push(new ShadowStringConcatenation(expressions ?? parts));
+    push(forest.stringConcatenationExpression(expressions ?? parts, null));
   }
 
   @override
@@ -1787,8 +1785,7 @@
   @override
   void endAwaitExpression(Token keyword, Token endToken) {
     debugEvent("AwaitExpression");
-    push(new ShadowAwaitExpression(popForValue())
-      ..fileOffset = offsetForToken(keyword));
+    push(forest.awaitExpression(popForValue(), keyword));
   }
 
   @override
@@ -2018,11 +2015,9 @@
     DartType type = pop();
     Expression operand = popForValue();
     bool isInverted = not != null;
-    var offset = offsetForToken(operator);
     Expression isExpression = isInverted
-        ? new ShadowIsNotExpression(operand, type, offset)
-        : new ShadowIsExpression(operand, type)
-      ..fileOffset = offset;
+        ? new ShadowIsNotExpression(operand, type, offsetForToken(operator))
+        : forest.isExpression(operand, type, operator);
     if (operand is VariableGet) {
       typePromoter.handleIsCheck(isExpression, isInverted, operand.variable,
           type, functionNestingLevel);
@@ -2058,9 +2053,8 @@
     Expression thenExpression = pop();
     Expression condition = pop();
     typePromoter.exitConditional();
-    push(new ShadowConditionalExpression(
-        condition, thenExpression, elseExpression)
-      ..fileOffset = question.offset);
+    push(forest.conditionalExpression(
+        condition, thenExpression, elseExpression, question));
   }
 
   @override
@@ -2317,8 +2311,7 @@
     debugEvent("UnaryPrefixExpression");
     var receiver = pop();
     if (optional("!", token)) {
-      push(
-          new ShadowNot(toValue(receiver))..fileOffset = offsetForToken(token));
+      push(forest.notExpression(toValue(receiver), token));
     } else {
       String operator = token.stringValue;
       if (optional("-", token)) {
@@ -2337,8 +2330,7 @@
       Expression receiverValue;
       if (receiver is ThisAccessor && receiver.isSuper) {
         isSuper = true;
-        receiverValue = new ShadowThisExpression()
-          ..fileOffset = offsetForToken(receiver.token);
+        receiverValue = forest.thisExpression(receiver.token);
       } else {
         receiverValue = toValue(receiver);
       }
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 8a34d1d..96757e9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -29,17 +29,23 @@
     show
         ShadowArguments,
         ShadowAsExpression,
+        ShadowAwaitExpression,
         ShadowBoolLiteral,
         ShadowCheckLibraryIsLoaded,
+        ShadowConditionalExpression,
         ShadowDoubleLiteral,
         ShadowIntLiteral,
+        ShadowIsExpression,
         ShadowListLiteral,
         ShadowLoadLibrary,
         ShadowMapLiteral,
+        ShadowNot,
         ShadowNullLiteral,
+        ShadowStringConcatenation,
         ShadowStringLiteral,
         ShadowSymbolLiteral,
         ShadowSyntheticExpression,
+        ShadowThisExpression,
         ShadowTypeLiteral;
 
 import 'forest.dart' show Forest;
@@ -162,6 +168,42 @@
   }
 
   @override
+  Expression awaitExpression(Expression operand, Token token) {
+    return new ShadowAwaitExpression(operand)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression conditionalExpression(Expression condition, Expression then,
+      Expression otherwise, Token token) {
+    return new ShadowConditionalExpression(condition, then, otherwise)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression isExpression(Expression operand, covariant type, Token token) {
+    return new ShadowIsExpression(operand, type)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression notExpression(Expression operand, Token token) {
+    return new ShadowNot(operand)..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression stringConcatenationExpression(
+      List<Expression> expressions, Token token) {
+    return new ShadowStringConcatenation(expressions)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression thisExpression(Token token) {
+    return new ShadowThisExpression()..fileOffset = offsetForToken(token);
+  }
+
+  @override
   bool isErroneousNode(TreeNode node) {
     if (node is ExpressionStatement) {
       ExpressionStatement statement = node;
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
index 8e79571..8b416be 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -434,7 +434,7 @@
 
   Expression buildSimpleRead() {
     if (!isSuper) {
-      return new ShadowThisExpression()..fileOffset = offsetForToken(token);
+      return forest.thisExpression(token);
     } else {
       return helper.buildCompileTimeError(messageSuperAsExpression,
           offsetForToken(token), lengthForToken(token));
@@ -471,7 +471,7 @@
         helper.warnUnresolvedMethod(name, offsetForToken(send.token),
             isSuper: isSuper);
       }
-      return helper.buildMethodInvocation(new ShadowThisExpression(), name,
+      return helper.buildMethodInvocation(forest.thisExpression(null), name,
           send.arguments, offsetForToken(send.token),
           isSuper: isSuper, interfaceTarget: getter);
     } else {
@@ -495,7 +495,7 @@
           messageSuperAsExpression, offset, noLength);
     } else {
       return helper.buildMethodInvocation(
-          new ShadowThisExpression(), callName, arguments, offset,
+          forest.thisExpression(null), callName, arguments, offset,
           isImplicitCall: true);
     }
   }
@@ -1073,7 +1073,7 @@
       interfaceTarget = null;
     }
     return helper.buildMethodInvocation(
-        new ShadowThisExpression(), name, arguments, offset,
+        forest.thisExpression(null), name, arguments, offset,
         interfaceTarget: interfaceTarget);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 8b7327f..f52b1fe 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -57,6 +57,21 @@
   Expression asExpression(
       Expression expression, covariant type, Location location);
 
+  Expression awaitExpression(Expression operand, Location location);
+
+  Expression conditionalExpression(Expression condition, Expression then,
+      Expression otherwise, Location location);
+
+  Expression isExpression(
+      Expression operand, covariant type, Location location);
+
+  Expression notExpression(Expression operand, Location location);
+
+  Expression stringConcatenationExpression(
+      List<Expression> expressions, Location location);
+
+  Expression thisExpression(Location location);
+
   bool isErroneousNode(covariant node);
 
   // TODO(ahe): Remove this method when all users are moved here.
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 6b91235..d384b5a 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
@@ -61,15 +61,12 @@
 
 export 'kernel_shadow_ast.dart'
     show
-        ShadowAsExpression,
         ShadowAssertInitializer,
         ShadowAssertStatement,
-        ShadowAwaitExpression,
         ShadowBlock,
         ShadowBreakStatement,
         ShadowCascadeExpression,
         ShadowComplexAssignment,
-        ShadowConditionalExpression,
         ShadowConstructorInvocation,
         ShadowContinueSwitchStatement,
         ShadowDeferredCheck,
@@ -86,14 +83,12 @@
         ShadowIllegalAssignment,
         ShadowIndexAssign,
         ShadowInvalidInitializer,
-        ShadowIsExpression,
         ShadowIsNotExpression,
         ShadowLabeledStatement,
         ShadowLogicalExpression,
         ShadowLoopAssignmentStatement,
         ShadowMethodInvocation,
         ShadowNamedFunctionExpression,
-        ShadowNot,
         ShadowNullAwareMethodInvocation,
         ShadowPropertyAssign,
         ShadowRedirectingInitializer,
@@ -102,13 +97,11 @@
         ShadowStaticAssignment,
         ShadowStaticGet,
         ShadowStaticInvocation,
-        ShadowStringConcatenation,
         ShadowSuperInitializer,
         ShadowSuperMethodInvocation,
         ShadowSuperPropertyGet,
         ShadowSwitchStatement,
         ShadowSyntheticExpression,
-        ShadowThisExpression,
         ShadowThrow,
         ShadowTryCatch,
         ShadowTryFinally,