| 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 library dev_compiler.src.info; | 7 library dev_compiler.src.info; |
| 8 | 8 |
| 9 import 'dart:mirrors'; | 9 import 'dart:mirrors'; |
| 10 | 10 |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 } | 205 } |
| 206 | 206 |
| 207 Cast get cast => _cast; | 207 Cast get cast => _cast; |
| 208 | 208 |
| 209 DartType _getConvertedType() => _cast.toType; | 209 DartType _getConvertedType() => _cast.toType; |
| 210 | 210 |
| 211 String get message => '$expression ($baseType) will need runtime check ' | 211 String get message => '$expression ($baseType) will need runtime check ' |
| 212 'to cast to type $convertedType'; | 212 'to cast to type $convertedType'; |
| 213 | 213 |
| 214 // Factory to create correct DownCast variant. | 214 // Factory to create correct DownCast variant. |
| 215 static StaticInfo create(TypeRules rules, Expression expression, Cast cast) { | 215 static StaticInfo create(TypeRules rules, Expression expression, Cast cast, |
| 216 {String reason}) { |
| 216 final fromT = cast.fromType; | 217 final fromT = cast.fromType; |
| 217 final toT = cast.toType; | 218 final toT = cast.toType; |
| 218 | 219 |
| 219 // toT <:_R fromT => to <: fromT | 220 // toT <:_R fromT => to <: fromT |
| 220 // NB: classes with call methods are subtypes of function | 221 // NB: classes with call methods are subtypes of function |
| 221 // types, but the function type is not assignable to the class | 222 // types, but the function type is not assignable to the class |
| 222 assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT)); | 223 assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT)); |
| 223 | 224 |
| 224 // Handle null call specially. | 225 // Handle null call specially. |
| 225 if (expression is NullLiteral) { | 226 if (expression is NullLiteral) { |
| 226 if (rules.isNonNullableType(toT)) { | 227 if (rules.isNonNullableType(toT)) { |
| 227 return new StaticTypeError(rules, expression, toT); | 228 reason = "null is invalid as a $toT"; |
| 229 return new StaticTypeError(rules, expression, toT, reason: reason); |
| 228 } else { | 230 } else { |
| 229 // We should only get here if some coercion is required. | 231 // We should only get here if some coercion is required. |
| 230 assert(rules.maybeNonNullableType(toT)); | 232 assert(rules.maybeNonNullableType(toT)); |
| 231 // TODO(vsm): Create a NullCast for this once we revisit nonnullability. | 233 // TODO(vsm): Create a NullCast for this once we revisit nonnullability. |
| 232 return new DownCastImplicit(rules, expression, cast); | 234 return new DownCastImplicit(rules, expression, cast); |
| 233 } | 235 } |
| 234 } | 236 } |
| 235 | 237 |
| 236 // Inference "casts": | 238 // Inference "casts": |
| 237 if (expression is Literal) { | 239 if (expression is Literal) { |
| 238 // fromT should be an exact type - this will almost certainly fail at | 240 // fromT should be an exact type - this will almost certainly fail at |
| 239 // runtime. | 241 // runtime. |
| 240 return new StaticTypeError(rules, expression, toT); | 242 return new StaticTypeError(rules, expression, toT, reason: reason); |
| 241 } | 243 } |
| 242 if (expression is FunctionExpression) { | 244 if (expression is FunctionExpression) { |
| 243 // fromT should be an exact type - this will almost certainly fail at | 245 // fromT should be an exact type - this will almost certainly fail at |
| 244 // runtime. | 246 // runtime. |
| 245 return new InferableClosure(rules, expression, cast); | 247 return new InferableClosure(rules, expression, cast); |
| 246 } | 248 } |
| 247 if (expression is InstanceCreationExpression) { | 249 if (expression is InstanceCreationExpression) { |
| 248 // fromT should be an exact type - this will almost certainly fail at | 250 // fromT should be an exact type - this will almost certainly fail at |
| 249 // runtime. | 251 // runtime. |
| 250 return new StaticTypeError(rules, expression, toT); | 252 return new StaticTypeError(rules, expression, toT, reason: reason); |
| 251 } | 253 } |
| 252 | 254 |
| 253 // Composite cast: these are more likely to fail. | 255 // Composite cast: these are more likely to fail. |
| 254 if (!rules.isGroundType(toT)) { | 256 if (!rules.isGroundType(toT)) { |
| 255 // This cast is (probably) due to our different treatment of dynamic. | 257 // This cast is (probably) due to our different treatment of dynamic. |
| 256 // It may be more likely to fail at runtime. | 258 // It may be more likely to fail at runtime. |
| 257 return new DownCastComposite(rules, expression, cast); | 259 return new DownCastComposite(rules, expression, cast); |
| 258 } | 260 } |
| 259 | 261 |
| 260 // Dynamic cast | 262 // Dynamic cast |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 final AstNode node; | 491 final AstNode node; |
| 490 | 492 |
| 491 StaticError(this.node); | 493 StaticError(this.node); |
| 492 | 494 |
| 493 Level get level => Level.SEVERE; | 495 Level get level => Level.SEVERE; |
| 494 } | 496 } |
| 495 | 497 |
| 496 class StaticTypeError extends StaticError { | 498 class StaticTypeError extends StaticError { |
| 497 final DartType baseType; | 499 final DartType baseType; |
| 498 final DartType expectedType; | 500 final DartType expectedType; |
| 501 String reason = null; |
| 499 | 502 |
| 500 StaticTypeError(TypeRules rules, Expression expression, this.expectedType) | 503 StaticTypeError(TypeRules rules, Expression expression, this.expectedType, |
| 504 {this.reason}) |
| 501 : baseType = rules.getStaticType(expression), | 505 : baseType = rules.getStaticType(expression), |
| 502 super(expression); | 506 super(expression); |
| 503 | 507 |
| 504 String get message => | 508 String get message => |
| 505 'Type check failed: $node ($baseType) is not of type $expectedType'; | 509 'Type check failed: $node ($baseType) is not of type $expectedType' + |
| 510 ((reason == null) ? '' : ' because $reason'); |
| 506 } | 511 } |
| 507 | 512 |
| 508 class InvalidVariableDeclaration extends StaticError { | 513 class InvalidVariableDeclaration extends StaticError { |
| 509 final DartType expectedType; | 514 final DartType expectedType; |
| 510 | 515 |
| 511 InvalidVariableDeclaration( | 516 InvalidVariableDeclaration( |
| 512 TypeRules rules, AstNode declaration, this.expectedType) | 517 TypeRules rules, AstNode declaration, this.expectedType) |
| 513 : super(declaration); | 518 : super(declaration); |
| 514 | 519 |
| 515 String get message => 'Type check failed: null is not of type $expectedType'; | 520 String get message => 'Type check failed: null is not of type $expectedType'; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 for (var cls in declarations.where((d) => d is ClassMirror)) { | 723 for (var cls in declarations.where((d) => d is ClassMirror)) { |
| 719 if (cls.isSubtypeOf(infoMirror)) { | 724 if (cls.isSubtypeOf(infoMirror)) { |
| 720 allTypes.add(cls); | 725 allTypes.add(cls); |
| 721 baseTypes.add(cls.superclass); | 726 baseTypes.add(cls.superclass); |
| 722 } | 727 } |
| 723 } | 728 } |
| 724 allTypes.removeAll(baseTypes); | 729 allTypes.removeAll(baseTypes); |
| 725 return new List<Type>.from(allTypes.map((mirror) => mirror.reflectedType)) | 730 return new List<Type>.from(allTypes.map((mirror) => mirror.reflectedType)) |
| 726 ..sort((t1, t2) => '$t1'.compareTo('$t2')); | 731 ..sort((t1, t2) => '$t1'.compareTo('$t2')); |
| 727 }(); | 732 }(); |
| OLD | NEW |