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>
This commit is contained in:
Brian Wilkerson 2018-05-07 23:55:03 +00:00 committed by commit-bot@chromium.org
parent 3002e47e36
commit 446668e95c
4 changed files with 100 additions and 56 deletions

View file

@ -73,12 +73,10 @@ class AstBuildingForest
}
@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 @@ class AstBuildingForest
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 @@ class AstBuildingForest
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);

View file

@ -1802,15 +1802,17 @@ class BodyBuilder<Arguments> extends ScopeListener<JumpTarget>
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 @@ class BodyBuilder<Arguments> extends ScopeListener<JumpTarget>
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 @@ class BodyBuilder<Arguments> extends ScopeListener<JumpTarget>
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 @@ class BodyBuilder<Arguments> extends ScopeListener<JumpTarget>
Expression condition = pop();
typePromoter.exitConditional();
push(forest.conditionalExpression(
condition, thenExpression, elseExpression, question));
condition, question, thenExpression, colon, elseExpression));
}
@override

View file

@ -36,6 +36,7 @@ import 'kernel_shadow_ast.dart'
ShadowDoubleLiteral,
ShadowIntLiteral,
ShadowIsExpression,
ShadowIsNotExpression,
ShadowListLiteral,
ShadowLoadLibrary,
ShadowMapLiteral,
@ -118,8 +119,16 @@ class Fangorn extends Forest<Expression, Statement, Token, Arguments> {
}
@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 @@ class Fangorn extends Forest<Expression, Statement, Token, Arguments> {
}
@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

View file

@ -9,6 +9,8 @@ import 'package:kernel/ast.dart' as kernel show Arguments;
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 @@ abstract class Forest<Expression, Statement, Location, Arguments> {
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 @@ abstract class Forest<Expression, Statement, Location, Arguments> {
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);