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

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

Issue 3006893002: Refactor fuzzy arrow hints. (Closed)
Patch Set: Reland and refactor fuzzy arrow hints. Created 3 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
6 // refactored to fit into analyzer. 6 // refactored to fit into analyzer.
7 library analyzer.src.task.strong.checker; 7 library analyzer.src.task.strong.checker;
8 8
9 import 'dart:collection'; 9 import 'dart:collection';
10 import 'package:analyzer/analyzer.dart'; 10 import 'package:analyzer/analyzer.dart';
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 /// needed, and if so records it. 765 /// needed, and if so records it.
766 /// 766 ///
767 /// If [from] is omitted, uses the static type of [expr]. 767 /// If [from] is omitted, uses the static type of [expr].
768 /// 768 ///
769 /// If [expr] does not require an implicit cast because it is not related to 769 /// If [expr] does not require an implicit cast because it is not related to
770 /// [to] or is already a subtype of it, does nothing. 770 /// [to] or is already a subtype of it, does nothing.
771 void _checkImplicitCast(Expression expr, DartType to, 771 void _checkImplicitCast(Expression expr, DartType to,
772 {DartType from, bool opAssign: false, bool isDeclarationCast: false}) { 772 {DartType from, bool opAssign: false, bool isDeclarationCast: false}) {
773 from ??= _getDefiniteType(expr); 773 from ??= _getDefiniteType(expr);
774 774
775 _hintOnFuzzyArrows(expr, to, from);
776
775 if (_needsImplicitCast(expr, to, 777 if (_needsImplicitCast(expr, to,
776 from: from, isDeclarationCast: isDeclarationCast) == 778 from: from, isDeclarationCast: isDeclarationCast) ==
777 true) { 779 true) {
778 _recordImplicitCast(expr, to, from: from, opAssign: opAssign); 780 _recordImplicitCast(expr, to, from: from, opAssign: opAssign);
779 } 781 }
780 } 782 }
781 783
782 /// Checks if the assignment is valid with respect to non-nullable types. 784 /// Checks if the assignment is valid with respect to non-nullable types.
783 /// Returns `false` if a nullable expression is assigned to a variable of 785 /// Returns `false` if a nullable expression is assigned to a variable of
784 /// non-nullable type and `true` otherwise. 786 /// non-nullable type and `true` otherwise.
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 // Dynamic as the parameter type is treated as bottom. A function with 1070 // Dynamic as the parameter type is treated as bottom. A function with
1069 // a dynamic parameter type requires a dynamic call in general. 1071 // a dynamic parameter type requires a dynamic call in general.
1070 // However, as an optimization, if we have an original definition, we know 1072 // However, as an optimization, if we have an original definition, we know
1071 // dynamic is reified as Object - in this case a regular call is fine. 1073 // dynamic is reified as Object - in this case a regular call is fine.
1072 if (hasStrictArrow(call.function)) { 1074 if (hasStrictArrow(call.function)) {
1073 return false; 1075 return false;
1074 } 1076 }
1075 return rules.anyParameterType(ft, (pt) => pt.isDynamic); 1077 return rules.anyParameterType(ft, (pt) => pt.isDynamic);
1076 } 1078 }
1077 1079
1080 void _hintOnFuzzyArrows(Expression expr, DartType to, DartType from) {
1081 // If it is a subtype with fuzzy arrows on,
1082 // check to see if it still is with them off.
1083 if (rules.isSubtypeOf(from, to)) {
1084 // Remove fuzzy arrows
1085 var cFrom = rules.typeToConcreteType(from);
1086 var cTo = rules.typeToConcreteType(to);
1087 // If still true, no warning needed
1088 if (rules.isSubtypeOf(cFrom, cTo)) return;
1089 _recordMessage(expr, HintCode.USES_DYNAMIC_AS_BOTTOM, [from, to]);
1090 }
1091 }
1092
1078 /// Returns true if we need an implicit cast of [expr] from [from] type to 1093 /// Returns true if we need an implicit cast of [expr] from [from] type to
1079 /// [to] type, returns false if no cast is needed, and returns null if the 1094 /// [to] type, returns false if no cast is needed, and returns null if the
1080 /// types are statically incompatible. 1095 /// types are statically incompatible.
1081 /// 1096 ///
1082 /// If [from] is omitted, uses the static type of [expr] 1097 /// If [from] is omitted, uses the static type of [expr]
1083 bool _needsImplicitCast(Expression expr, DartType to, 1098 bool _needsImplicitCast(Expression expr, DartType to,
1084 {DartType from, bool isDeclarationCast: false}) { 1099 {DartType from, bool isDeclarationCast: false}) {
1085 from ??= _getDefiniteType(expr); 1100 from ??= _getDefiniteType(expr);
1086 1101
1087 if (!_checkNonNullAssignment(expr, to, from)) return false; 1102 if (!_checkNonNullAssignment(expr, to, from)) return false;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 var severity = 1232 var severity =
1218 (processor != null) ? processor.severity : errorCode.errorSeverity; 1233 (processor != null) ? processor.severity : errorCode.errorSeverity;
1219 1234
1220 if (severity == ErrorSeverity.ERROR) { 1235 if (severity == ErrorSeverity.ERROR) {
1221 _failure = true; 1236 _failure = true;
1222 } 1237 }
1223 if (errorCode.type == ErrorType.HINT && 1238 if (errorCode.type == ErrorType.HINT &&
1224 errorCode.name.startsWith('STRONG_MODE_TOP_LEVEL_')) { 1239 errorCode.name.startsWith('STRONG_MODE_TOP_LEVEL_')) {
1225 severity = ErrorSeverity.ERROR; 1240 severity = ErrorSeverity.ERROR;
1226 } 1241 }
1227 if (severity != ErrorSeverity.INFO || _options.strongModeHints) { 1242 if (severity != ErrorSeverity.INFO ||
1243 _options.strongModeHints ||
1244 errorCode == HintCode.USES_DYNAMIC_AS_BOTTOM) {
1228 int begin = node is AnnotatedNode 1245 int begin = node is AnnotatedNode
1229 ? node.firstTokenAfterCommentAndMetadata.offset 1246 ? node.firstTokenAfterCommentAndMetadata.offset
1230 : node.offset; 1247 : node.offset;
1231 int length = node.end - begin; 1248 int length = node.end - begin;
1232 var source = resolutionMap 1249 var source = resolutionMap
1233 .elementDeclaredByCompilationUnit(node.root as CompilationUnit) 1250 .elementDeclaredByCompilationUnit(node.root as CompilationUnit)
1234 .source; 1251 .source;
1235 var error = 1252 var error =
1236 new AnalysisError(source, begin, length, errorCode, arguments); 1253 new AnalysisError(source, begin, length, errorCode, arguments);
1237 reporter.onError(error); 1254 reporter.onError(error);
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 } 1998 }
1982 1999
1983 /// If node is a [ClassDeclaration] returns its members, otherwise if node is 2000 /// If node is a [ClassDeclaration] returns its members, otherwise if node is
1984 /// a [ClassTypeAlias] this returns an empty list. 2001 /// a [ClassTypeAlias] this returns an empty list.
1985 WithClause _withClause(Declaration node) { 2002 WithClause _withClause(Declaration node) {
1986 return node is ClassDeclaration 2003 return node is ClassDeclaration
1987 ? node.withClause 2004 ? node.withClause
1988 : (node as ClassTypeAlias).withClause; 2005 : (node as ClassTypeAlias).withClause;
1989 } 2006 }
1990 } 2007 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/dart/error/hint_codes.dart ('k') | pkg/analyzer/test/src/task/strong/checker_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698