Index: lib/src/checker/checker.dart |
diff --git a/lib/src/checker/checker.dart b/lib/src/checker/checker.dart |
index 78b1a20e68d0344c324558a1439fda3877777e07..72283659a9aac082765c216eaa04e7f6c866d9b8 100644 |
--- a/lib/src/checker/checker.dart |
+++ b/lib/src/checker/checker.dart |
@@ -398,7 +398,7 @@ class CodeChecker extends RecursiveAstVisitor { |
_checkCompoundAssignment(node); |
} else { |
DartType staticType = _rules.getStaticType(node.leftHandSide); |
- node.rightHandSide = checkAssignment(node.rightHandSide, staticType); |
+ checkAssignment(node.rightHandSide, staticType); |
} |
node.visitChildren(this); |
} |
@@ -423,7 +423,7 @@ class CodeChecker extends RecursiveAstVisitor { |
void visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
var field = node.fieldName; |
DartType staticType = _rules.elementType(field.staticElement); |
- node.expression = checkAssignment(node.expression, staticType); |
+ checkAssignment(node.expression, staticType); |
node.visitChildren(this); |
} |
@@ -437,33 +437,33 @@ class CodeChecker extends RecursiveAstVisitor { |
: node.loopVariable.identifier; |
var iteratorType = loopVariable.staticType; |
var checkedType = iterableType.substitute4([iteratorType]); |
- node.iterable = checkAssignment(expr, checkedType); |
+ checkAssignment(expr, checkedType); |
node.visitChildren(this); |
} |
@override |
void visitForStatement(ForStatement node) { |
if (node.condition != null) { |
- node.condition = checkBoolean(node.condition); |
+ checkBoolean(node.condition); |
} |
node.visitChildren(this); |
} |
@override |
void visitIfStatement(IfStatement node) { |
- node.condition = checkBoolean(node.condition); |
+ checkBoolean(node.condition); |
node.visitChildren(this); |
} |
@override |
void visitDoStatement(DoStatement node) { |
- node.condition = checkBoolean(node.condition); |
+ checkBoolean(node.condition); |
node.visitChildren(this); |
} |
@override |
void visitWhileStatement(WhileStatement node) { |
- node.condition = checkBoolean(node.condition); |
+ checkBoolean(node.condition); |
node.visitChildren(this); |
} |
@@ -485,7 +485,7 @@ class CodeChecker extends RecursiveAstVisitor { |
} |
var elements = node.elements; |
for (int i = 0; i < elements.length; i++) { |
- elements[i] = checkArgument(elements[i], type); |
+ checkArgument(elements[i], type); |
} |
super.visitListLiteral(node); |
} |
@@ -502,14 +502,14 @@ class CodeChecker extends RecursiveAstVisitor { |
var entries = node.entries; |
for (int i = 0; i < entries.length; i++) { |
var entry = entries[i]; |
- entry.key = checkArgument(entry.key, ktype); |
- entry.value = checkArgument(entry.value, vtype); |
+ checkArgument(entry.key, ktype); |
+ checkArgument(entry.value, vtype); |
} |
super.visitMapLiteral(node); |
} |
// Check invocations |
- bool checkArgumentList(ArgumentList node, FunctionType type) { |
+ void checkArgumentList(ArgumentList node, FunctionType type) { |
NodeList<Expression> list = node.arguments; |
int len = list.length; |
for (int i = 0; i < len; ++i) { |
@@ -527,19 +527,17 @@ class CodeChecker extends RecursiveAstVisitor { |
} |
DartType expectedType = _rules.elementType(element); |
if (expectedType == null) expectedType = _rules.provider.dynamicType; |
- list[i] = checkArgument(arg, expectedType); |
+ checkArgument(arg, expectedType); |
} |
- return true; |
} |
- Expression checkArgument(Expression arg, DartType expectedType) { |
+ void checkArgument(Expression arg, DartType expectedType) { |
// Preserve named argument structure, so their immediate parent is the |
// method invocation. |
if (arg is NamedExpression) { |
- arg.expression = checkAssignment(arg.expression, expectedType); |
- return arg; |
+ arg = (arg as NamedExpression).expression; |
} |
- return checkAssignment(arg, expectedType); |
+ checkAssignment(arg, expectedType); |
} |
void checkFunctionApplication( |
@@ -569,8 +567,7 @@ class CodeChecker extends RecursiveAstVisitor { |
void visitRedirectingConstructorInvocation( |
RedirectingConstructorInvocation node) { |
var type = node.staticElement.type; |
- bool checked = checkArgumentList(node.argumentList, type); |
- assert(checked); |
+ checkArgumentList(node.argumentList, type); |
node.visitChildren(this); |
} |
@@ -581,8 +578,7 @@ class CodeChecker extends RecursiveAstVisitor { |
_recordMessage(new MissingTypeError(node)); |
} else { |
var type = node.staticElement.type; |
- bool checked = checkArgumentList(node.argumentList, type); |
- assert(checked); |
+ checkArgumentList(node.argumentList, type); |
} |
node.visitChildren(this); |
} |
@@ -606,22 +602,21 @@ class CodeChecker extends RecursiveAstVisitor { |
} |
} |
- Expression _checkReturn(Expression expression, AstNode node) { |
+ void _checkReturn(Expression expression, AstNode node) { |
var type = _getFunctionType(_getOwnerFunction(node)).returnType; |
// TODO(vsm): Enforce void or dynamic (to void?) when expression is null. |
- if (expression == null) return null; |
- return checkAssignment(expression, type); |
+ if (expression != null) checkAssignment(expression, type); |
} |
@override |
void visitExpressionFunctionBody(ExpressionFunctionBody node) { |
- node.expression = _checkReturn(node.expression, node); |
+ _checkReturn(node.expression, node); |
node.visitChildren(this); |
} |
@override |
void visitReturnStatement(ReturnStatement node) { |
- node.expression = _checkReturn(node.expression, node); |
+ _checkReturn(node.expression, node); |
node.visitChildren(this); |
} |
@@ -657,8 +652,7 @@ class CodeChecker extends RecursiveAstVisitor { |
_recordMessage(staticInfo); |
} |
} else { |
- var staticInfo = checkAssignment(defaultValue, parameterType); |
- if (staticInfo is! StaticError) node.defaultValue = staticInfo; |
+ checkAssignment(defaultValue, parameterType); |
} |
node.visitChildren(this); |
@@ -711,7 +705,7 @@ class CodeChecker extends RecursiveAstVisitor { |
for (VariableDeclaration variable in node.variables) { |
var initializer = variable.initializer; |
if (initializer != null) { |
- variable.initializer = checkAssignment(initializer, dartType); |
+ checkAssignment(initializer, dartType); |
} else if (_rules.maybeNonNullableType(dartType)) { |
var element = variable.element; |
if (element is FieldElement && !element.isStatic) { |
@@ -761,7 +755,7 @@ class CodeChecker extends RecursiveAstVisitor { |
@override |
void visitPrefixExpression(PrefixExpression node) { |
if (node.operator.type == TokenType.BANG) { |
- node.operand = checkBoolean(node.operand); |
+ checkBoolean(node.operand); |
} else { |
_checkUnary(node); |
} |
@@ -806,8 +800,7 @@ class CodeChecker extends RecursiveAstVisitor { |
// Analyzer should enforce number of parameter types, but check in |
// case we have erroneous input. |
if (type.normalParameterTypes.isNotEmpty) { |
- node.rightOperand = |
- checkArgument(node.rightOperand, type.normalParameterTypes[0]); |
+ checkArgument(node.rightOperand, type.normalParameterTypes[0]); |
} |
} else { |
// TODO(vsm): Assert that the analyzer found an error here? |
@@ -818,8 +811,8 @@ class CodeChecker extends RecursiveAstVisitor { |
switch (op.type) { |
case TokenType.AMPERSAND_AMPERSAND: |
case TokenType.BAR_BAR: |
- node.leftOperand = checkBoolean(node.leftOperand); |
- node.rightOperand = checkBoolean(node.rightOperand); |
+ checkBoolean(node.leftOperand); |
+ checkBoolean(node.rightOperand); |
break; |
case TokenType.BANG_EQ: |
break; |
@@ -832,7 +825,7 @@ class CodeChecker extends RecursiveAstVisitor { |
@override |
void visitConditionalExpression(ConditionalExpression node) { |
- node.condition = checkBoolean(node.condition); |
+ checkBoolean(node.condition); |
node.visitChildren(this); |
} |
@@ -847,7 +840,7 @@ class CodeChecker extends RecursiveAstVisitor { |
// Analyzer should enforce number of parameter types, but check in |
// case we have erroneous input. |
if (type.normalParameterTypes.isNotEmpty) { |
- node.index = checkArgument(node.index, type.normalParameterTypes[0]); |
+ checkArgument(node.index, type.normalParameterTypes[0]); |
} |
} else { |
// TODO(vsm): Assert that the analyzer found an error here? |
@@ -863,18 +856,15 @@ class CodeChecker extends RecursiveAstVisitor { |
/// Analyzer checks boolean conversions, but we need to check too, because |
/// it uses the default assignability rules that allow `dynamic` and `Object` |
/// to be assigned to bool with no message. |
- Expression checkBoolean(Expression expr) => |
+ void checkBoolean(Expression expr) => |
checkAssignment(expr, _rules.provider.boolType); |
- Expression checkAssignment(Expression expr, DartType type) { |
+ void checkAssignment(Expression expr, DartType type) { |
if (expr is ParenthesizedExpression) { |
- expr.expression = checkAssignment(expr.expression, type); |
+ checkAssignment(expr.expression, type); |
} else { |
- final staticInfo = _rules.checkAssignment(expr, type, _constantContext); |
- _recordMessage(staticInfo); |
- if (staticInfo is Conversion) expr = staticInfo; |
+ _recordMessage(_rules.checkAssignment(expr, type, _constantContext)); |
} |
- return expr; |
} |
DartType _specializedBinaryReturnType( |
@@ -933,9 +923,6 @@ class CodeChecker extends RecursiveAstVisitor { |
// compound operators in the int += num and num += dynamic cases. |
staticInfo = DownCast.create( |
_rules, expr.rightHandSide, Coercion.cast(rhsType, lhsType)); |
- if (staticInfo is DownCast) { |
- expr.rightHandSide = staticInfo; |
- } |
rhsType = lhsType; |
} else { |
// Static type error |
@@ -945,12 +932,11 @@ class CodeChecker extends RecursiveAstVisitor { |
} |
// Check the rhs type |
- if (staticInfo is! Conversion) { |
+ if (staticInfo is! CoercionInfo) { |
var paramType = paramTypes.first; |
staticInfo = _rules.checkAssignment( |
expr.rightHandSide, paramType, _constantContext); |
_recordMessage(staticInfo); |
- if (staticInfo is Conversion) expr.rightHandSide = staticInfo; |
} |
} |
} |
@@ -963,5 +949,9 @@ class CodeChecker extends RecursiveAstVisitor { |
if (info == null) return; |
if (info.level >= logger.Level.SEVERE) _failure = true; |
_reporter.log(info); |
+ if (info is CoercionInfo) { |
+ assert(CoercionInfo.get(info.node) == null); |
+ CoercionInfo.set(info.node, info); |
+ } |
} |
} |