Add required information for three more cases

Change-Id: I3c7093f14eb0164bf8a282f21f2917f1cb3f36a2
Reviewed-on: https://dart-review.googlesource.com/54069
Reviewed-by: Dan Rubel <danrubel@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index b8e5bd5..44c005f 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -73,12 +73,10 @@
   }
 
   @override
-  Expression conditionalExpression(Expression condition,
-      Expression thenExpression, Expression elseExpression, Token location) {
-    // TODO(brianwilkerson) Get the missing information.
-    return astFactory.conditionalExpression(condition, null /* question */,
-        thenExpression, null /* colon */, elseExpression);
-  }
+  Expression conditionalExpression(Expression condition, Token question,
+          Expression thenExpression, Token colon, Expression elseExpression) =>
+      astFactory.conditionalExpression(
+          condition, question, thenExpression, colon, elseExpression);
 
   @override
   kernel.DartType getTypeAt(Object typeArguments, int index) {
@@ -94,11 +92,9 @@
   bool isErroneousNode(covariant node) => false; // ???
 
   @override
-  Expression isExpression(Expression expression, type, Token location) {
-    // TODO(brianwilkerson) Get the missing information.
-    return astFactory.isExpression(
-        expression, null /* isOperator */, null /* notOperator */, type);
-  }
+  Expression isExpression(Expression expression, Token isOperator,
+          Token notOperator, Object type) =>
+      astFactory.isExpression(expression, isOperator, notOperator, type);
 
   @override
   Expression literalBool(bool value, Token location) =>
@@ -126,16 +122,18 @@
           constKeyword, typeArguments, leftBracket, expressions, rightBracket);
 
   @override
-  Expression literalMap(covariant keyType, covariant valueType,
-      covariant List entries, bool isConst, Token location) {
-    // TODO(brianwilkerson) Get the missing information.
-    return astFactory.mapLiteral(
-        null /* constKeyword */,
-        null /* typeArguments */,
-        null /* leftBracket */,
-        entries,
-        null /* rightBracket */);
-  }
+  Expression literalMap(
+          Token constKeyword,
+          bool isConst,
+          covariant keyType,
+          covariant valueType,
+          Object typeArguments,
+          Token leftBracket,
+          covariant List entries,
+          Token rightBracket,
+          Token location) =>
+      astFactory.mapLiteral(
+          constKeyword, typeArguments, leftBracket, entries, rightBracket);
 
   @override
   Expression literalNull(Token location) => astFactory.nullLiteral(location);
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 75b233a..0e04698 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1802,15 +1802,17 @@
     Object typeArguments = pop();
     DartType typeArgument;
     if (typeArguments != null) {
-      typeArgument = forest.getTypeAt(typeArguments, 0);
       if (forest.getTypeCount(typeArguments) > 1) {
-        typeArgument = null;
         addProblem(
             fasta.messageListLiteralTooManyTypeArguments,
             offsetForToken(beginToken),
             lengthOfSpan(beginToken, beginToken.endGroup));
-      } else if (library.loader.target.strongMode) {
-        typeArgument = instantiateToBounds(typeArgument, coreTypes.objectClass);
+      } else {
+        typeArgument = forest.getTypeAt(typeArguments, 0);
+        if (library.loader.target.strongMode) {
+          typeArgument =
+              instantiateToBounds(typeArgument, coreTypes.objectClass);
+        }
       }
     }
     push(forest.literalList(
@@ -1850,35 +1852,34 @@
     debugEvent("LiteralMap");
     List entries = forest.mapEntryList(count);
     popList(count, entries);
-    List<DartType> typeArguments = pop();
+    Object typeArguments = pop();
     DartType keyType;
     DartType valueType;
     if (typeArguments != null) {
-      if (typeArguments.length != 2) {
-        keyType = null;
-        valueType = null;
+      if (forest.getTypeCount(typeArguments) != 2) {
         addProblem(
             fasta.messageListLiteralTypeArgumentMismatch,
             offsetForToken(beginToken),
             lengthOfSpan(beginToken, beginToken.endGroup));
       } else {
+        keyType = forest.getTypeAt(typeArguments, 0);
+        valueType = forest.getTypeAt(typeArguments, 1);
         if (library.loader.target.strongMode) {
-          keyType =
-              instantiateToBounds(typeArguments[0], coreTypes.objectClass);
-          valueType =
-              instantiateToBounds(typeArguments[1], coreTypes.objectClass);
-        } else {
-          keyType = typeArguments[0];
-          valueType = typeArguments[1];
+          keyType = instantiateToBounds(keyType, coreTypes.objectClass);
+          valueType = instantiateToBounds(valueType, coreTypes.objectClass);
         }
       }
     }
 
     push(forest.literalMap(
+        constKeyword,
+        constKeyword != null || constantContext == ConstantContext.inferred,
         keyType,
         valueType,
+        typeArguments,
+        beginToken,
         entries,
-        constKeyword != null || constantContext == ConstantContext.inferred,
+        endToken,
         constKeyword ?? beginToken));
   }
 
@@ -2019,9 +2020,7 @@
     DartType type = pop();
     Expression operand = popForValue();
     bool isInverted = not != null;
-    Expression isExpression = isInverted
-        ? new ShadowIsNotExpression(operand, type, offsetForToken(operator))
-        : forest.isExpression(operand, type, operator);
+    Expression isExpression = forest.isExpression(operand, operator, not, type);
     if (operand is VariableGet) {
       typePromoter.handleIsCheck(isExpression, isInverted, operand.variable,
           type, functionNestingLevel);
@@ -2058,7 +2057,7 @@
     Expression condition = pop();
     typePromoter.exitConditional();
     push(forest.conditionalExpression(
-        condition, thenExpression, elseExpression, question));
+        condition, question, thenExpression, colon, elseExpression));
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index a100779..fac7751 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -36,6 +36,7 @@
         ShadowDoubleLiteral,
         ShadowIntLiteral,
         ShadowIsExpression,
+        ShadowIsNotExpression,
         ShadowListLiteral,
         ShadowLoadLibrary,
         ShadowMapLiteral,
@@ -118,8 +119,16 @@
   }
 
   @override
-  ShadowMapLiteral literalMap(DartType keyType, DartType valueType,
-      List<MapEntry> entries, bool isConst, Token token) {
+  ShadowMapLiteral literalMap(
+      Token constKeyword,
+      bool isConst,
+      DartType keyType,
+      DartType valueType,
+      Object typeArguments,
+      Token leftBracket,
+      List<MapEntry> entries,
+      Token rightBracket,
+      Token token) {
     return new ShadowMapLiteral(entries,
         keyType: keyType, valueType: valueType, isConst: isConst)
       ..fileOffset = offsetForToken(token);
@@ -188,16 +197,21 @@
   }
 
   @override
-  Expression conditionalExpression(Expression condition, Expression then,
-      Expression otherwise, Token token) {
-    return new ShadowConditionalExpression(condition, then, otherwise)
-      ..fileOffset = offsetForToken(token);
+  Expression conditionalExpression(Expression condition, Token question,
+      Expression thenExpression, Token colon, Expression elseExpression) {
+    return new ShadowConditionalExpression(
+        condition, thenExpression, elseExpression)
+      ..fileOffset = offsetForToken(question);
   }
 
   @override
-  Expression isExpression(Expression operand, covariant type, Token token) {
-    return new ShadowIsExpression(operand, type)
-      ..fileOffset = offsetForToken(token);
+  Expression isExpression(
+      Expression operand, isOperator, Token notOperator, covariant type) {
+    int offset = offsetForToken(isOperator);
+    if (notOperator != null) {
+      return new ShadowIsNotExpression(operand, type, offset);
+    }
+    return new ShadowIsExpression(operand, type)..fileOffset = offset;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index fc2f482..1a1b99c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -9,6 +9,8 @@
 import 'package:kernel/ast.dart';
 
 /// A tree factory.
+///
+/// For now, the [Location] is always a token.
 abstract class Forest<Expression, Statement, Location, Arguments> {
   Arguments arguments(List<Expression> positional, Location location,
       {covariant List types, covariant List named});
@@ -60,8 +62,31 @@
       Location rightBracket,
       Location location);
 
-  Expression literalMap(covariant keyType, covariant valueType,
-      covariant List entries, bool isConst, Location location);
+  /// Return a representation of a map literal. The [constKeyword] is the
+  /// location of the `const` keyword, or `null` if there is no keyword. The
+  /// [isConst] is `true` if either the `const` keyword is not-`null` or if the
+  /// map literal is in a const context. The [keyType] is the representation of
+  /// the first type argument preceding the map literal, or `null` if there are
+  /// not exactly two type arguments or if the first type argument cannot be
+  /// resolved. The [valueType] is the representation of the second type
+  /// argument preceding the map literal, or `null` if there are not exactly two
+  /// type arguments or if the second type argument cannot be resolved. The
+  /// [typeArguments] is the representation of all of the type arguments
+  /// preceding the map literal, or `null` if there are no type arguments. The
+  /// [leftBracket] is the location of the `{`. The list of [entries] is a
+  /// list of the representations of the map entries. The [rightBracket] is
+  /// the location of the `}`. The [location] is the location of the first token
+  /// in the map literal.
+  Expression literalMap(
+      Location constKeyword,
+      bool isConst,
+      covariant keyType,
+      covariant valueType,
+      Object typeArguments,
+      Location leftBracket,
+      covariant List entries,
+      Location rightBracket,
+      Location location);
 
   /// Return a representation of a null literal at the given [location].
   Expression literalNull(Location location);
@@ -104,11 +129,19 @@
 
   Expression awaitExpression(Expression operand, Location location);
 
-  Expression conditionalExpression(Expression condition, Expression then,
-      Expression otherwise, Location location);
+  /// Return a representation of a conditional expression. The [condition] is
+  /// the condition. The [question] is the `?`. The [thenExpression] is the
+  /// expression following the question mark. The [colon] is the `:`. The
+  /// [elseExpression] is the expression following the colon.
+  Expression conditionalExpression(Expression condition, Location question,
+      Expression thenExpression, Location colon, Expression elseExpression);
 
-  Expression isExpression(
-      Expression operand, covariant type, Location location);
+  /// Return a representation of an `is` expression. The [operand] is the
+  /// representation of the left operand. The [isOperator] is the `is` operator.
+  /// The [notOperator] is either the `!` or `null` if the test is not negated.
+  /// The [type] is a representation of the type that is the right operand.
+  Expression isExpression(Expression operand, Location isOperator,
+      Location notOperator, covariant type);
 
   Expression notExpression(Expression operand, Location location);