| 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 library dev_compiler.src.checker.rules; | 5 library dev_compiler.src.checker.rules; |
| 6 | 6 |
| 7 import 'package:analyzer/src/generated/ast.dart'; | 7 import 'package:analyzer/src/generated/ast.dart'; |
| 8 import 'package:analyzer/src/generated/element.dart'; | 8 import 'package:analyzer/src/generated/element.dart'; |
| 9 import 'package:analyzer/src/generated/resolver.dart'; | 9 import 'package:analyzer/src/generated/resolver.dart'; |
| 10 | 10 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 bool isIntType(DartType t) => t == provider.intType; | 35 bool isIntType(DartType t) => t == provider.intType; |
| 36 bool isNumType(DartType t) => t == provider.intType.superclass; | 36 bool isNumType(DartType t) => t == provider.intType.superclass; |
| 37 bool isStringType(DartType t) => t == provider.stringType; | 37 bool isStringType(DartType t) => t == provider.stringType; |
| 38 bool isNonNullableType(DartType t) => false; | 38 bool isNonNullableType(DartType t) => false; |
| 39 bool maybeNonNullableType(DartType t) => false; | 39 bool maybeNonNullableType(DartType t) => false; |
| 40 | 40 |
| 41 StaticInfo checkAssignment(Expression expr, DartType t, bool constContext); | 41 StaticInfo checkAssignment(Expression expr, DartType t, bool constContext); |
| 42 | 42 |
| 43 DartType getStaticType(Expression expr) => expr.staticType; | 43 DartType getStaticType(Expression expr) => expr.staticType; |
| 44 | 44 |
| 45 /// Given a type t, if t is an interface type with a call method |
| 46 /// defined, return the function type for the call method, otherwise |
| 47 /// return null. |
| 48 FunctionType getCallMethodType(DartType t) { |
| 49 if (t is InterfaceType) { |
| 50 ClassElement element = t.element; |
| 51 InheritanceManager manager = new InheritanceManager(element.library); |
| 52 FunctionType callType = manager.lookupMemberType(t, "call"); |
| 53 return callType; |
| 54 } |
| 55 return null; |
| 56 } |
| 57 |
| 58 /// Given an expression, return its type assuming it is |
| 59 /// in the caller position of a call (that is, accounting |
| 60 /// for the possibility of a call method). Returns null |
| 61 /// if expression is not statically callable. |
| 62 FunctionType getTypeAsCaller(Expression applicand) { |
| 63 var t = getStaticType(applicand); |
| 64 if (t is InterfaceType) { |
| 65 return getCallMethodType(t); |
| 66 } |
| 67 if (t is FunctionType) return t; |
| 68 return null; |
| 69 } |
| 70 |
| 45 DartType elementType(Element e); | 71 DartType elementType(Element e); |
| 46 | 72 |
| 47 bool isDynamic(DartType t); | 73 bool isDynamic(DartType t); |
| 48 bool isDynamicTarget(Expression expr); | 74 bool isDynamicTarget(Expression expr); |
| 49 bool isDynamicCall(Expression call); | 75 bool isDynamicCall(Expression call); |
| 50 } | 76 } |
| 51 | 77 |
| 52 class DartRules extends TypeRules { | 78 class DartRules extends TypeRules { |
| 53 DartRules(TypeProvider provider) : super(provider); | 79 DartRules(TypeProvider provider) : super(provider); |
| 54 | 80 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 var typeArguments = t.typeArguments; | 204 var typeArguments = t.typeArguments; |
| 179 for (var typeArgument in typeArguments) { | 205 for (var typeArgument in typeArguments) { |
| 180 if (!_isTop(typeArgument)) return false; | 206 if (!_isTop(typeArgument)) return false; |
| 181 } | 207 } |
| 182 return true; | 208 return true; |
| 183 } | 209 } |
| 184 | 210 |
| 185 throw new StateError("Unexpected type"); | 211 throw new StateError("Unexpected type"); |
| 186 } | 212 } |
| 187 | 213 |
| 188 FunctionType getCallMethodType(DartType t) { | |
| 189 if (t is InterfaceType) { | |
| 190 ClassElement element = t.element; | |
| 191 InheritanceManager manager = new InheritanceManager(element.library); | |
| 192 FunctionType callType = manager.lookupMemberType(t, "call"); | |
| 193 return callType; | |
| 194 } | |
| 195 return null; | |
| 196 } | |
| 197 | |
| 198 /// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC | 214 /// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC |
| 199 /// checker to determine whether f1 would be a subtype of f2 if the return | 215 /// checker to determine whether f1 would be a subtype of f2 if the return |
| 200 /// type of f1 is set to match f2's return type. | 216 /// type of f1 is set to match f2's return type. |
| 201 // [fuzzyArrows] indicates whether or not the f1 and f2 should be | 217 // [fuzzyArrows] indicates whether or not the f1 and f2 should be |
| 202 // treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as | 218 // treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as |
| 203 // bottom). | 219 // bottom). |
| 204 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, | 220 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, |
| 205 {bool fuzzyArrows: true, bool ignoreReturn: false}) { | 221 {bool fuzzyArrows: true, bool ignoreReturn: false}) { |
| 206 final r1s = f1.normalParameterTypes; | 222 final r1s = f1.normalParameterTypes; |
| 207 final o1s = f1.optionalParameterTypes; | 223 final o1s = f1.optionalParameterTypes; |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 bool isDynamic(DartType t) => options.ignoreTypes || t.isDynamic; | 545 bool isDynamic(DartType t) => options.ignoreTypes || t.isDynamic; |
| 530 | 546 |
| 531 /// Returns `true` if the target expression is dynamic. | 547 /// Returns `true` if the target expression is dynamic. |
| 532 bool isDynamicTarget(Expression target) => | 548 bool isDynamicTarget(Expression target) => |
| 533 options.ignoreTypes || utils.isDynamicTarget(target); | 549 options.ignoreTypes || utils.isDynamicTarget(target); |
| 534 | 550 |
| 535 /// Returns `true` if the expression is a dynamic function call or method | 551 /// Returns `true` if the expression is a dynamic function call or method |
| 536 /// invocation. | 552 /// invocation. |
| 537 bool isDynamicCall(Expression call) { | 553 bool isDynamicCall(Expression call) { |
| 538 if (options.ignoreTypes) return true; | 554 if (options.ignoreTypes) return true; |
| 539 var t = getStaticType(call); | 555 var t = getTypeAsCaller(call); |
| 540 // TODO(jmesserly): fix handling of types with `call` methods. These are not | 556 // TODO(leafp): This will currently return true if t is Function |
| 541 // FunctionType, but they also aren't dynamic calls. | 557 // This is probably the most correct thing to do for now, since |
| 542 if (t.isDynamic || t.isDartCoreFunction || t is! FunctionType) { | 558 // this code is also used by the back end. Maybe revisit at some |
| 543 return true; | 559 // point? |
| 544 } | 560 if (t == null) return true; |
| 545 // Dynamic as the parameter type is treated as bottom. A function with | 561 // Dynamic as the parameter type is treated as bottom. A function with |
| 546 // a dynamic parameter type requires a dynamic call in general. | 562 // a dynamic parameter type requires a dynamic call in general. |
| 547 // However, as an optimization, if we have an original definition, we know | 563 // However, as an optimization, if we have an original definition, we know |
| 548 // dynamic is reified as Object - in this case a regular call is fine. | 564 // dynamic is reified as Object - in this case a regular call is fine. |
| 549 if (call is SimpleIdentifier) { | 565 if (call is SimpleIdentifier) { |
| 550 var element = call.staticElement; | 566 var element = call.staticElement; |
| 551 if (element is FunctionElement || element is MethodElement) { | 567 if (element is FunctionElement || element is MethodElement) { |
| 552 // An original declaration. | 568 // An original declaration. |
| 553 return false; | 569 return false; |
| 554 } | 570 } |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 var entries = e.entries; | 839 var entries = e.entries; |
| 824 bool inferEntry(MapLiteralEntry entry) { | 840 bool inferEntry(MapLiteralEntry entry) { |
| 825 return _inferExpression(entry.key, kType, errors) && | 841 return _inferExpression(entry.key, kType, errors) && |
| 826 _inferExpression(entry.value, vType, errors); | 842 _inferExpression(entry.value, vType, errors); |
| 827 } | 843 } |
| 828 var b = entries.every(inferEntry); | 844 var b = entries.every(inferEntry); |
| 829 if (b) annotateMapLiteral(e, targs); | 845 if (b) annotateMapLiteral(e, targs); |
| 830 return b; | 846 return b; |
| 831 } | 847 } |
| 832 } | 848 } |
| OLD | NEW |