Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: pkg/analyzer/lib/src/task/strong/checker.dart

Issue 1780783002: Don't report redundant type errors in strong mode. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Stop type propagation in test. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/type_system.dart ('k') | pkg/analyzer/lib/src/task/strong/info.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/task/strong/checker.dart
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 9831fb67ca9a59b79fcc1490f6dae3b952eff307..acf01ff9b4a0f044a607405403f188888c1ab400 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -145,7 +145,7 @@ class CodeChecker extends RecursiveAstVisitor {
if (expr is ParenthesizedExpression) {
checkAssignment(expr.expression, type);
} else {
- _recordMessage(_checkAssignment(expr, type));
+ _checkDowncast(expr, type);
}
}
@@ -565,25 +565,15 @@ class CodeChecker extends RecursiveAstVisitor {
node.visitChildren(this);
}
- StaticInfo _checkAssignment(Expression expr, DartType toT) {
- final fromT = _getStaticType(expr);
- final Coercion c = _coerceTo(fromT, toT);
- if (c is Identity) return null;
- if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
- if (c is Cast) return DownCast.create(rules, expr, c);
- assert(false);
- return null;
- }
-
void _checkCompoundAssignment(AssignmentExpression expr) {
var op = expr.operator.type;
assert(op.isAssignmentOperator && op != TokenType.EQ);
var methodElement = expr.staticElement;
if (methodElement == null) {
- // Dynamic invocation
+ // Dynamic invocation.
_recordDynamicInvoke(expr, expr.leftHandSide);
} else {
- // Sanity check the operator
+ // Sanity check the operator.
assert(methodElement.isOperator);
var functionType = methodElement.type;
var paramTypes = functionType.normalParameterTypes;
@@ -591,7 +581,7 @@ class CodeChecker extends RecursiveAstVisitor {
assert(functionType.namedParameterTypes.isEmpty);
assert(functionType.optionalParameterTypes.isEmpty);
- // Check the lhs type
+ // Check the LHS type.
var staticInfo;
var rhsType = _getStaticType(expr.rightHandSide);
var lhsType = _getStaticType(expr.leftHandSide);
@@ -606,10 +596,9 @@ class CodeChecker extends RecursiveAstVisitor {
// This is also slightly different from spec, but allows us to keep
// compound operators in the int += num and num += dynamic cases.
staticInfo = DownCast.create(
- rules, expr.rightHandSide, Coercion.cast(rhsType, lhsType));
+ rules, expr.rightHandSide, new Cast(rhsType, lhsType));
rhsType = lhsType;
} else {
- // Static type error
staticInfo = new StaticTypeError(rules, expr, lhsType);
}
_recordMessage(staticInfo);
@@ -618,8 +607,7 @@ class CodeChecker extends RecursiveAstVisitor {
// Check the rhs type
if (staticInfo is! CoercionInfo) {
var paramType = paramTypes.first;
- staticInfo = _checkAssignment(expr.rightHandSide, paramType);
- _recordMessage(staticInfo);
+ _checkDowncast(expr.rightHandSide, paramType);
}
}
}
@@ -675,12 +663,18 @@ class CodeChecker extends RecursiveAstVisitor {
}
}
- Coercion _coerceTo(DartType fromT, DartType toT) {
- // We can use anything as void
- if (toT.isVoid) return Coercion.identity(toT);
+ /// Records a [DownCast] of [expr] to [toT], if there is one.
+ ///
+ /// If [expr] does not require a downcast because it is not related to [toT]
+ /// or is already a subtype of it, does nothing.
+ void _checkDowncast(Expression expr, DartType toT) {
+ DartType fromT = _getStaticType(expr);
+
+ // We can use anything as void.
+ if (toT.isVoid) return;
- // fromT <: toT, no coercion needed
- if (rules.isSubtypeOf(fromT, toT)) return Coercion.identity(toT);
+ // fromT <: toT, no coercion needed.
+ if (rules.isSubtypeOf(fromT, toT)) return;
// TODO(vsm): We can get rid of the second clause if we disallow
// all sideways casts - see TODO below.
@@ -690,11 +684,14 @@ class CodeChecker extends RecursiveAstVisitor {
// well for consistency.
if ((fromT is FunctionType && rules.getCallMethodType(toT) != null) ||
(toT is FunctionType && rules.getCallMethodType(fromT) != null)) {
- return Coercion.error();
+ return;
}
// Downcast if toT <: fromT
- if (rules.isSubtypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
+ if (rules.isSubtypeOf(toT, fromT)) {
+ _recordMessage(DownCast.create(rules, expr, new Cast(fromT, toT)));
+ return;
+ }
// TODO(vsm): Once we have generic methods, we should delete this
// workaround. These sideways casts are always ones we warn about
@@ -707,10 +704,8 @@ class CodeChecker extends RecursiveAstVisitor {
// Iterable<T> for some concrete T (e.g. Object). These are unrelated
// in the restricted system, but List<dynamic> <: Iterable<T> in dart.
if (fromT.isAssignableTo(toT)) {
- return Coercion.cast(fromT, toT);
+ _recordMessage(DownCast.create(rules, expr, new Cast(fromT, toT)));
}
-
- return Coercion.error();
}
// Produce a coercion which coerces something of type fromT
« no previous file with comments | « pkg/analyzer/lib/src/generated/type_system.dart ('k') | pkg/analyzer/lib/src/task/strong/info.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698