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 |