| OLD | NEW |
| 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 /// Defines static information collected by the type checker and used later by | 5 /// Defines static information collected by the type checker and used later by |
| 6 /// emitters to generate code. | 6 /// emitters to generate code. |
| 7 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be | 7 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be |
| 8 // refactored to fit into analyzer. | 8 // refactored to fit into analyzer. |
| 9 library analyzer.src.task.strong.info; | 9 library analyzer.src.task.strong.info; |
| 10 | 10 |
| 11 import 'package:analyzer/src/generated/ast.dart'; | 11 import 'package:analyzer/src/generated/ast.dart'; |
| 12 import 'package:analyzer/src/generated/element.dart'; | 12 import 'package:analyzer/src/generated/element.dart'; |
| 13 import 'package:analyzer/src/generated/error.dart'; | 13 import 'package:analyzer/src/generated/error.dart'; |
| 14 | 14 import 'package:analyzer/src/generated/type_system.dart'; |
| 15 import 'rules.dart'; | |
| 16 | 15 |
| 17 // A down cast due to a variable declaration to a ground type. E.g., | 16 // A down cast due to a variable declaration to a ground type. E.g., |
| 18 // T x = expr; | 17 // T x = expr; |
| 19 // where T is ground. We exclude non-ground types as these behave differently | 18 // where T is ground. We exclude non-ground types as these behave differently |
| 20 // compared to standard Dart. | 19 // compared to standard Dart. |
| 21 class AssignmentCast extends DownCast { | 20 class AssignmentCast extends DownCast { |
| 22 AssignmentCast(TypeRules rules, Expression expression, Cast cast) | 21 AssignmentCast(TypeSystem rules, Expression expression, Cast cast) |
| 23 : super._internal(rules, expression, cast); | 22 : super._internal(rules, expression, cast); |
| 24 | 23 |
| 25 @override | 24 @override |
| 26 String get name => 'STRONG_MODE_ASSIGNMENT_CAST'; | 25 String get name => 'STRONG_MODE_ASSIGNMENT_CAST'; |
| 27 | 26 |
| 28 toErrorCode() => new HintCode(name, message); | 27 toErrorCode() => new HintCode(name, message); |
| 29 } | 28 } |
| 30 | 29 |
| 31 // Coercion which casts one type to another | 30 // Coercion which casts one type to another |
| 32 class Cast extends Coercion { | 31 class Cast extends Coercion { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 49 // could not be generated. The code generator should not see | 48 // could not be generated. The code generator should not see |
| 50 // these. | 49 // these. |
| 51 class CoercionError extends Coercion { | 50 class CoercionError extends Coercion { |
| 52 CoercionError() : super(null, null); | 51 CoercionError() : super(null, null); |
| 53 } | 52 } |
| 54 | 53 |
| 55 /// Implicitly injected expression conversion. | 54 /// Implicitly injected expression conversion. |
| 56 abstract class CoercionInfo extends StaticInfo { | 55 abstract class CoercionInfo extends StaticInfo { |
| 57 static const String _propertyName = 'dev_compiler.src.info.CoercionInfo'; | 56 static const String _propertyName = 'dev_compiler.src.info.CoercionInfo'; |
| 58 | 57 |
| 59 final TypeRules rules; | 58 final TypeSystem rules; |
| 60 | 59 |
| 61 final Expression node; | 60 final Expression node; |
| 62 | 61 |
| 63 CoercionInfo(this.rules, this.node); | 62 CoercionInfo(this.rules, this.node); |
| 64 | 63 |
| 65 DartType get baseType => rules.getStaticType(node); | 64 DartType get baseType => node.staticType ?? DynamicTypeImpl.instance; |
| 66 DartType get convertedType; | 65 DartType get convertedType; |
| 67 | 66 |
| 68 String get message; | 67 String get message; |
| 69 DartType get staticType => convertedType; | 68 DartType get staticType => convertedType; |
| 70 | 69 |
| 71 toErrorCode() => new HintCode(name, message); | 70 toErrorCode() => new HintCode(name, message); |
| 72 | 71 |
| 73 /// Gets the coercion info associated with this node. | 72 /// Gets the coercion info associated with this node. |
| 74 static CoercionInfo get(AstNode node) => node.getProperty(_propertyName); | 73 static CoercionInfo get(AstNode node) => node.getProperty(_propertyName); |
| 75 | 74 |
| 76 /// Sets the coercion info associated with this node. | 75 /// Sets the coercion info associated with this node. |
| 77 static CoercionInfo set(AstNode node, CoercionInfo info) { | 76 static CoercionInfo set(AstNode node, CoercionInfo info) { |
| 78 node.setProperty(_propertyName, info); | 77 node.setProperty(_propertyName, info); |
| 79 return info; | 78 return info; |
| 80 } | 79 } |
| 81 } | 80 } |
| 82 | 81 |
| 83 // Base class for all casts from base type to sub type. | 82 // Base class for all casts from base type to sub type. |
| 84 abstract class DownCast extends CoercionInfo { | 83 abstract class DownCast extends CoercionInfo { |
| 85 Cast _cast; | 84 Cast _cast; |
| 86 | 85 |
| 87 DownCast._internal(TypeRules rules, Expression expression, this._cast) | 86 DownCast._internal( |
| 87 TypeSystem rules, Expression expression, this._cast) |
| 88 : super(rules, expression) { | 88 : super(rules, expression) { |
| 89 assert(_cast.toType != baseType && | 89 assert(_cast.toType != baseType && |
| 90 _cast.fromType == baseType && | 90 _cast.fromType == baseType && |
| 91 (baseType.isDynamic || | 91 (baseType.isDynamic || |
| 92 // Call methods make the following non-redundant | 92 // Call methods make the following non-redundant |
| 93 _cast.toType.isSubtypeOf(baseType) || | 93 _cast.toType.isSubtypeOf(baseType) || |
| 94 baseType.isAssignableTo(_cast.toType))); | 94 baseType.isAssignableTo(_cast.toType))); |
| 95 } | 95 } |
| 96 | 96 |
| 97 @override List<Object> get arguments => [node, baseType, convertedType]; | 97 @override List<Object> get arguments => [node, baseType, convertedType]; |
| 98 | 98 |
| 99 Cast get cast => _cast; | 99 Cast get cast => _cast; |
| 100 | 100 |
| 101 DartType get convertedType => _cast.toType; | 101 DartType get convertedType => _cast.toType; |
| 102 @override String get message => '{0} ({1}) will need runtime check ' | 102 @override String get message => '{0} ({1}) will need runtime check ' |
| 103 'to cast to type {2}'; | 103 'to cast to type {2}'; |
| 104 | 104 |
| 105 // Factory to create correct DownCast variant. | 105 // Factory to create correct DownCast variant. |
| 106 static StaticInfo create(TypeRules rules, Expression expression, Cast cast, | 106 static StaticInfo create( |
| 107 StrongTypeSystemImpl rules, Expression expression, Cast cast, |
| 107 {String reason}) { | 108 {String reason}) { |
| 108 final fromT = cast.fromType; | 109 final fromT = cast.fromType; |
| 109 final toT = cast.toType; | 110 final toT = cast.toType; |
| 110 | 111 |
| 111 // toT <:_R fromT => to <: fromT | 112 // toT <:_R fromT => to <: fromT |
| 112 // NB: classes with call methods are subtypes of function | 113 // NB: classes with call methods are subtypes of function |
| 113 // types, but the function type is not assignable to the class | 114 // types, but the function type is not assignable to the class |
| 114 assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT)); | 115 assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT)); |
| 115 | 116 |
| 116 // Handle null call specially. | 117 // Handle null call specially. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 131 return new UninferredClosure(rules, expression, cast); | 132 return new UninferredClosure(rules, expression, cast); |
| 132 } | 133 } |
| 133 if (expression is InstanceCreationExpression) { | 134 if (expression is InstanceCreationExpression) { |
| 134 // fromT should be an exact type - this will almost certainly fail at | 135 // fromT should be an exact type - this will almost certainly fail at |
| 135 // runtime. | 136 // runtime. |
| 136 return new StaticTypeError(rules, expression, toT, reason: reason); | 137 return new StaticTypeError(rules, expression, toT, reason: reason); |
| 137 } | 138 } |
| 138 | 139 |
| 139 // TODO(vsm): Change this to an assert when we have generic methods and | 140 // TODO(vsm): Change this to an assert when we have generic methods and |
| 140 // fix TypeRules._coerceTo to disallow implicit sideways casts. | 141 // fix TypeRules._coerceTo to disallow implicit sideways casts. |
| 141 if (!rules.isSubTypeOf(toT, fromT)) { | 142 if (!rules.isSubtypeOf(toT, fromT)) { |
| 142 assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT)); | 143 assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT)); |
| 143 return new DownCastComposite(rules, expression, cast); | 144 return new DownCastComposite(rules, expression, cast); |
| 144 } | 145 } |
| 145 | 146 |
| 146 // Composite cast: these are more likely to fail. | 147 // Composite cast: these are more likely to fail. |
| 147 if (!rules.isGroundType(toT)) { | 148 if (!rules.isGroundType(toT)) { |
| 148 // This cast is (probably) due to our different treatment of dynamic. | 149 // This cast is (probably) due to our different treatment of dynamic. |
| 149 // It may be more likely to fail at runtime. | 150 // It may be more likely to fail at runtime. |
| 150 if (fromT is InterfaceType) { | 151 if (fromT is InterfaceType) { |
| 151 // For class types, we'd like to allow non-generic down casts, e.g., | 152 // For class types, we'd like to allow non-generic down casts, e.g., |
| (...skipping 23 matching lines...) Expand all Loading... |
| 175 return new DownCastImplicit(rules, expression, cast); | 176 return new DownCastImplicit(rules, expression, cast); |
| 176 } | 177 } |
| 177 } | 178 } |
| 178 | 179 |
| 179 // | 180 // |
| 180 // Implicit down casts. These are only injected by the compiler by flag. | 181 // Implicit down casts. These are only injected by the compiler by flag. |
| 181 // | 182 // |
| 182 // A down cast to a non-ground type. These behave differently from standard | 183 // A down cast to a non-ground type. These behave differently from standard |
| 183 // Dart and may be more likely to fail at runtime. | 184 // Dart and may be more likely to fail at runtime. |
| 184 class DownCastComposite extends DownCast { | 185 class DownCastComposite extends DownCast { |
| 185 DownCastComposite(TypeRules rules, Expression expression, Cast cast) | 186 DownCastComposite( |
| 187 TypeSystem rules, Expression expression, Cast cast) |
| 186 : super._internal(rules, expression, cast); | 188 : super._internal(rules, expression, cast); |
| 187 | 189 |
| 188 @override | 190 @override |
| 189 String get name => 'STRONG_MODE_DOWN_CAST_COMPOSITE'; | 191 String get name => 'STRONG_MODE_DOWN_CAST_COMPOSITE'; |
| 190 | 192 |
| 191 toErrorCode() => new StaticTypeWarningCode(name, message); | 193 toErrorCode() => new StaticTypeWarningCode(name, message); |
| 192 } | 194 } |
| 193 | 195 |
| 194 // A down cast to a non-ground type. These behave differently from standard | 196 // A down cast to a non-ground type. These behave differently from standard |
| 195 // Dart and may be more likely to fail at runtime. | 197 // Dart and may be more likely to fail at runtime. |
| 196 class DownCastImplicit extends DownCast { | 198 class DownCastImplicit extends DownCast { |
| 197 DownCastImplicit(TypeRules rules, Expression expression, Cast cast) | 199 DownCastImplicit(TypeSystem rules, Expression expression, Cast cast) |
| 198 : super._internal(rules, expression, cast); | 200 : super._internal(rules, expression, cast); |
| 199 | 201 |
| 200 @override | 202 @override |
| 201 String get name => 'STRONG_MODE_DOWN_CAST_IMPLICIT'; | 203 String get name => 'STRONG_MODE_DOWN_CAST_IMPLICIT'; |
| 202 | 204 |
| 203 toErrorCode() => new HintCode(name, message); | 205 toErrorCode() => new HintCode(name, message); |
| 204 } | 206 } |
| 205 | 207 |
| 206 // A down cast from dynamic to T. | 208 // A down cast from dynamic to T. |
| 207 class DynamicCast extends DownCast { | 209 class DynamicCast extends DownCast { |
| 208 DynamicCast(TypeRules rules, Expression expression, Cast cast) | 210 DynamicCast(TypeSystem rules, Expression expression, Cast cast) |
| 209 : super._internal(rules, expression, cast); | 211 : super._internal(rules, expression, cast); |
| 210 | 212 |
| 211 @override | 213 @override |
| 212 String get name => 'STRONG_MODE_DYNAMIC_CAST'; | 214 String get name => 'STRONG_MODE_DYNAMIC_CAST'; |
| 213 | 215 |
| 214 toErrorCode() => new HintCode(name, message); | 216 toErrorCode() => new HintCode(name, message); |
| 215 } | 217 } |
| 216 | 218 |
| 217 class DynamicInvoke extends CoercionInfo { | 219 class DynamicInvoke extends CoercionInfo { |
| 218 static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke'; | 220 static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke'; |
| 219 | 221 |
| 220 DynamicInvoke(TypeRules rules, Expression expression) | 222 DynamicInvoke(TypeSystem rules, Expression expression) |
| 221 : super(rules, expression); | 223 : super(rules, expression); |
| 222 DartType get convertedType => rules.provider.dynamicType; | 224 DartType get convertedType => DynamicTypeImpl.instance; |
| 223 String get message => '{0} requires dynamic invoke'; | 225 String get message => '{0} requires dynamic invoke'; |
| 224 | 226 |
| 225 @override | 227 @override |
| 226 String get name => 'STRONG_MODE_DYNAMIC_INVOKE'; | 228 String get name => 'STRONG_MODE_DYNAMIC_INVOKE'; |
| 227 | 229 |
| 228 toErrorCode() => new HintCode(name, message); | 230 toErrorCode() => new HintCode(name, message); |
| 229 | 231 |
| 230 /// Whether this [node] is the target of a dynamic operation. | 232 /// Whether this [node] is the target of a dynamic operation. |
| 231 static bool get(AstNode node) { | 233 static bool get(AstNode node) { |
| 232 var value = node.getProperty(_propertyName); | 234 var value = node.getProperty(_propertyName); |
| 233 return value != null ? value : false; | 235 return value != null ? value : false; |
| 234 } | 236 } |
| 235 | 237 |
| 236 /// Sets whether this node is the target of a dynamic operation. | 238 /// Sets whether this node is the target of a dynamic operation. |
| 237 static bool set(AstNode node, bool value) { | 239 static bool set(AstNode node, bool value) { |
| 238 // Free the storage for things that aren't dynamic. | 240 // Free the storage for things that aren't dynamic. |
| 239 if (value == false) value = null; | 241 if (value == false) value = null; |
| 240 node.setProperty(_propertyName, value); | 242 node.setProperty(_propertyName, value); |
| 241 return value; | 243 return value; |
| 242 } | 244 } |
| 243 } | 245 } |
| 244 | 246 |
| 245 // The identity coercion | 247 // The identity coercion |
| 246 class Identity extends Coercion { | 248 class Identity extends Coercion { |
| 247 Identity(DartType fromType) : super(fromType, fromType); | 249 Identity(DartType fromType) : super(fromType, fromType); |
| 248 } | 250 } |
| 249 | 251 |
| 250 // Standard / unspecialized inferred type | 252 // Standard / unspecialized inferred type |
| 251 class InferredType extends InferredTypeBase { | 253 class InferredType extends InferredTypeBase { |
| 252 InferredType(TypeRules rules, Expression expression, DartType type) | 254 InferredType(TypeSystem rules, Expression expression, DartType type) |
| 253 : super._internal(rules, expression, type); | 255 : super._internal(rules, expression, type); |
| 254 | 256 |
| 255 @override | 257 @override |
| 256 String get name => 'STRONG_MODE_INFERRED_TYPE'; | 258 String get name => 'STRONG_MODE_INFERRED_TYPE'; |
| 257 | 259 |
| 258 // Factory to create correct InferredType variant. | 260 // Factory to create correct InferredType variant. |
| 259 static InferredTypeBase create( | 261 static InferredTypeBase create( |
| 260 TypeRules rules, Expression expression, DartType type) { | 262 TypeSystem rules, Expression expression, DartType type) { |
| 261 // Specialized inference: | 263 // Specialized inference: |
| 262 if (expression is Literal) { | 264 if (expression is Literal) { |
| 263 return new InferredTypeLiteral(rules, expression, type); | 265 return new InferredTypeLiteral(rules, expression, type); |
| 264 } | 266 } |
| 265 if (expression is InstanceCreationExpression) { | 267 if (expression is InstanceCreationExpression) { |
| 266 return new InferredTypeAllocation(rules, expression, type); | 268 return new InferredTypeAllocation(rules, expression, type); |
| 267 } | 269 } |
| 268 if (expression is FunctionExpression) { | 270 if (expression is FunctionExpression) { |
| 269 return new InferredTypeClosure(rules, expression, type); | 271 return new InferredTypeClosure(rules, expression, type); |
| 270 } | 272 } |
| 271 return new InferredType(rules, expression, type); | 273 return new InferredType(rules, expression, type); |
| 272 } | 274 } |
| 273 } | 275 } |
| 274 | 276 |
| 275 // An inferred type for a non-literal allocation site. | 277 // An inferred type for a non-literal allocation site. |
| 276 class InferredTypeAllocation extends InferredTypeBase { | 278 class InferredTypeAllocation extends InferredTypeBase { |
| 277 InferredTypeAllocation(TypeRules rules, Expression expression, DartType type) | 279 InferredTypeAllocation( |
| 280 TypeSystem rules, Expression expression, DartType type) |
| 278 : super._internal(rules, expression, type); | 281 : super._internal(rules, expression, type); |
| 279 | 282 |
| 280 @override | 283 @override |
| 281 String get name => 'STRONG_MODE_INFERRED_TYPE_ALLOCATION'; | 284 String get name => 'STRONG_MODE_INFERRED_TYPE_ALLOCATION'; |
| 282 } | 285 } |
| 283 | 286 |
| 284 // An inferred type for the wrapped expression, which may need to be | 287 // An inferred type for the wrapped expression, which may need to be |
| 285 // reified into the term | 288 // reified into the term |
| 286 abstract class InferredTypeBase extends CoercionInfo { | 289 abstract class InferredTypeBase extends CoercionInfo { |
| 287 final DartType _type; | 290 final DartType _type; |
| 288 | 291 |
| 289 InferredTypeBase._internal(TypeRules rules, Expression expression, this._type) | 292 InferredTypeBase._internal( |
| 293 TypeSystem rules, Expression expression, this._type) |
| 290 : super(rules, expression); | 294 : super(rules, expression); |
| 291 | 295 |
| 292 @override List get arguments => [node, type]; | 296 @override List get arguments => [node, type]; |
| 293 DartType get convertedType => type; | 297 DartType get convertedType => type; |
| 294 @override String get message => '{0} has inferred type {1}'; | 298 @override String get message => '{0} has inferred type {1}'; |
| 295 DartType get type => _type; | 299 DartType get type => _type; |
| 296 | 300 |
| 297 toErrorCode() => new HintCode(name, message); | 301 toErrorCode() => new HintCode(name, message); |
| 298 } | 302 } |
| 299 | 303 |
| 300 // An inferred type for a closure expression | 304 // An inferred type for a closure expression |
| 301 class InferredTypeClosure extends InferredTypeBase { | 305 class InferredTypeClosure extends InferredTypeBase { |
| 302 InferredTypeClosure(TypeRules rules, Expression expression, DartType type) | 306 InferredTypeClosure( |
| 307 TypeSystem rules, Expression expression, DartType type) |
| 303 : super._internal(rules, expression, type); | 308 : super._internal(rules, expression, type); |
| 304 | 309 |
| 305 @override | 310 @override |
| 306 String get name => 'STRONG_MODE_INFERRED_TYPE_CLOSURE'; | 311 String get name => 'STRONG_MODE_INFERRED_TYPE_CLOSURE'; |
| 307 } | 312 } |
| 308 | 313 |
| 309 // An inferred type for a literal expression. | 314 // An inferred type for a literal expression. |
| 310 class InferredTypeLiteral extends InferredTypeBase { | 315 class InferredTypeLiteral extends InferredTypeBase { |
| 311 InferredTypeLiteral(TypeRules rules, Expression expression, DartType type) | 316 InferredTypeLiteral( |
| 317 TypeSystem rules, Expression expression, DartType type) |
| 312 : super._internal(rules, expression, type); | 318 : super._internal(rules, expression, type); |
| 313 | 319 |
| 314 @override | 320 @override |
| 315 String get name => 'STRONG_MODE_INFERRED_TYPE_LITERAL'; | 321 String get name => 'STRONG_MODE_INFERRED_TYPE_LITERAL'; |
| 316 } | 322 } |
| 317 | 323 |
| 318 class InvalidFieldOverride extends InvalidOverride { | 324 class InvalidFieldOverride extends InvalidOverride { |
| 319 InvalidFieldOverride(AstNode node, ExecutableElement element, | 325 InvalidFieldOverride(AstNode node, ExecutableElement element, |
| 320 InterfaceType base, DartType subType, DartType baseType) | 326 InterfaceType base, DartType subType, DartType baseType) |
| 321 : super(node, element, base, subType, baseType); | 327 : super(node, element, base, subType, baseType); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 ? 'Base class introduces an $lcErrorName' | 384 ? 'Base class introduces an $lcErrorName' |
| 379 : (fromMixin ? 'Mixin introduces an $lcErrorName' : errorName); | 385 : (fromMixin ? 'Mixin introduces an $lcErrorName' : errorName); |
| 380 return '$intro. The type of {0}.{1} ({2}) is not a ' | 386 return '$intro. The type of {0}.{1} ({2}) is not a ' |
| 381 'subtype of {3}.{1} ({4}).'; | 387 'subtype of {3}.{1} ({4}).'; |
| 382 } | 388 } |
| 383 } | 389 } |
| 384 | 390 |
| 385 class InvalidParameterDeclaration extends StaticError { | 391 class InvalidParameterDeclaration extends StaticError { |
| 386 final DartType expectedType; | 392 final DartType expectedType; |
| 387 | 393 |
| 388 InvalidParameterDeclaration( | 394 InvalidParameterDeclaration(TypeSystem rules, |
| 389 TypeRules rules, FormalParameter declaration, this.expectedType) | 395 FormalParameter declaration, this.expectedType) |
| 390 : super(declaration); | 396 : super(declaration); |
| 391 | 397 |
| 392 @override List<Object> get arguments => [node, expectedType]; | 398 @override List<Object> get arguments => [node, expectedType]; |
| 393 @override String get message => 'Type check failed: {0} is not of type {1}'; | 399 @override String get message => 'Type check failed: {0} is not of type {1}'; |
| 394 @override | 400 @override |
| 395 String get name => 'STRONG_MODE_INVALID_PARAMETER_DECLARATION'; | 401 String get name => 'STRONG_MODE_INVALID_PARAMETER_DECLARATION'; |
| 396 } | 402 } |
| 397 | 403 |
| 398 /// Dart constructors have one weird quirk, illustrated with this example: | 404 /// Dart constructors have one weird quirk, illustrated with this example: |
| 399 /// | 405 /// |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 "list (see http://goo.gl/q1T4BB): {0}"; | 437 "list (see http://goo.gl/q1T4BB): {0}"; |
| 432 | 438 |
| 433 @override | 439 @override |
| 434 String get name => 'STRONG_MODE_INVALID_SUPER_INVOCATION'; | 440 String get name => 'STRONG_MODE_INVALID_SUPER_INVOCATION'; |
| 435 } | 441 } |
| 436 | 442 |
| 437 class InvalidVariableDeclaration extends StaticError { | 443 class InvalidVariableDeclaration extends StaticError { |
| 438 final DartType expectedType; | 444 final DartType expectedType; |
| 439 | 445 |
| 440 InvalidVariableDeclaration( | 446 InvalidVariableDeclaration( |
| 441 TypeRules rules, AstNode declaration, this.expectedType) | 447 TypeSystem rules, AstNode declaration, this.expectedType) |
| 442 : super(declaration); | 448 : super(declaration); |
| 443 | 449 |
| 444 @override List<Object> get arguments => [expectedType]; | 450 @override List<Object> get arguments => [expectedType]; |
| 445 @override String get message => 'Type check failed: null is not of type {0}'; | 451 @override String get message => 'Type check failed: null is not of type {0}'; |
| 446 | 452 |
| 447 @override | 453 @override |
| 448 String get name => 'STRONG_MODE_INVALID_VARIABLE_DECLARATION'; | 454 String get name => 'STRONG_MODE_INVALID_VARIABLE_DECLARATION'; |
| 449 } | 455 } |
| 450 | 456 |
| 451 class NonGroundTypeCheckInfo extends StaticInfo { | 457 class NonGroundTypeCheckInfo extends StaticInfo { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 // TODO(jmesserly): review the usage of error codes. We probably want our own, | 532 // TODO(jmesserly): review the usage of error codes. We probably want our own, |
| 527 // as well as some DDC specific [ErrorType]s. | 533 // as well as some DDC specific [ErrorType]s. |
| 528 ErrorCode toErrorCode(); | 534 ErrorCode toErrorCode(); |
| 529 } | 535 } |
| 530 | 536 |
| 531 class StaticTypeError extends StaticError { | 537 class StaticTypeError extends StaticError { |
| 532 final DartType baseType; | 538 final DartType baseType; |
| 533 final DartType expectedType; | 539 final DartType expectedType; |
| 534 String reason = null; | 540 String reason = null; |
| 535 | 541 |
| 536 StaticTypeError(TypeRules rules, Expression expression, this.expectedType, | 542 StaticTypeError( |
| 543 TypeSystem rules, Expression expression, this.expectedType, |
| 537 {this.reason}) | 544 {this.reason}) |
| 538 : baseType = rules.getStaticType(expression), | 545 : baseType = expression.staticType ?? DynamicTypeImpl.instance, |
| 539 super(expression); | 546 super(expression); |
| 540 | 547 |
| 541 @override List<Object> get arguments => [node, baseType, expectedType]; | 548 @override List<Object> get arguments => [node, baseType, expectedType]; |
| 542 @override String get message => | 549 @override String get message => |
| 543 'Type check failed: {0} ({1}) is not of type {2}' + | 550 'Type check failed: {0} ({1}) is not of type {2}' + |
| 544 ((reason == null) ? '' : ' because $reason'); | 551 ((reason == null) ? '' : ' because $reason'); |
| 545 | 552 |
| 546 @override | 553 @override |
| 547 String get name => 'STRONG_MODE_STATIC_TYPE_ERROR'; | 554 String get name => 'STRONG_MODE_STATIC_TYPE_ERROR'; |
| 548 } | 555 } |
| 549 | 556 |
| 550 // | 557 // |
| 551 // Temporary "casts" of allocation sites - literals, constructor invocations, | 558 // Temporary "casts" of allocation sites - literals, constructor invocations, |
| 552 // and closures. These should be handled by contextual inference. In most | 559 // and closures. These should be handled by contextual inference. In most |
| 553 // cases, inference will be sufficient, though in some it may unmask an actual | 560 // cases, inference will be sufficient, though in some it may unmask an actual |
| 554 // error: e.g., | 561 // error: e.g., |
| 555 // List<int> l = [1, 2, 3]; // Inference succeeds | 562 // List<int> l = [1, 2, 3]; // Inference succeeds |
| 556 // List<String> l = [1, 2, 3]; // Inference reveals static type error | 563 // List<String> l = [1, 2, 3]; // Inference reveals static type error |
| 557 // We're marking all as warnings for now. | 564 // We're marking all as warnings for now. |
| 558 // | 565 // |
| 559 // TODO(vsm,leafp): Remove this. | 566 // TODO(vsm,leafp): Remove this. |
| 560 class UninferredClosure extends DownCast { | 567 class UninferredClosure extends DownCast { |
| 561 UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast) | 568 UninferredClosure( |
| 569 TypeSystem rules, FunctionExpression expression, Cast cast) |
| 562 : super._internal(rules, expression, cast); | 570 : super._internal(rules, expression, cast); |
| 563 | 571 |
| 564 @override | 572 @override |
| 565 String get name => 'STRONG_MODE_UNINFERRED_CLOSURE'; | 573 String get name => 'STRONG_MODE_UNINFERRED_CLOSURE'; |
| 566 | 574 |
| 567 toErrorCode() => new StaticTypeWarningCode(name, message); | 575 toErrorCode() => new StaticTypeWarningCode(name, message); |
| 568 } | 576 } |
| OLD | NEW |