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);