| 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 |
| 11 import '../../strong_mode.dart' show StrongModeOptions; | 11 import '../../strong_mode.dart' show StrongModeOptions; |
| 12 import '../info.dart'; | 12 import '../info.dart'; |
| 13 import '../utils.dart' as utils; | 13 import '../utils.dart' as utils; |
| 14 | 14 |
| 15 abstract class TypeRules { | 15 class TypeRules { |
| 16 final TypeProvider provider; | 16 final TypeProvider provider; |
| 17 | 17 |
| 18 /// Map of fields / properties / methods on Object. | 18 /// Map of fields / properties / methods on Object. |
| 19 final Map<String, DartType> objectMembers; | 19 final Map<String, DartType> objectMembers; |
| 20 | 20 |
| 21 TypeRules(TypeProvider provider) | 21 final StrongModeOptions options; |
| 22 DownwardsInference inferrer; |
| 23 |
| 24 TypeRules(TypeProvider provider, {this.options}) |
| 22 : provider = provider, | 25 : provider = provider, |
| 23 objectMembers = utils.getObjectMemberMap(provider); | 26 objectMembers = utils.getObjectMemberMap(provider) { |
| 24 | 27 inferrer = new DownwardsInference(this); |
| 25 bool isSubTypeOf(DartType t1, DartType t2); | 28 } |
| 26 bool isAssignable(DartType t1, DartType t2); | |
| 27 | |
| 28 bool isGroundType(DartType t) => true; | |
| 29 // TODO(vsm): The default implementation is not ignoring the return type, | |
| 30 // only the restricted override is. | |
| 31 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, | |
| 32 {bool fuzzyArrows: true, bool ignoreReturn: false}) => | |
| 33 isSubTypeOf(f1, f2); | |
| 34 | |
| 35 StaticInfo checkAssignment(Expression expr, DartType t); | |
| 36 | |
| 37 DartType getStaticType(Expression expr) => expr.staticType; | |
| 38 | 29 |
| 39 /// Given a type t, if t is an interface type with a call method | 30 /// Given a type t, if t is an interface type with a call method |
| 40 /// defined, return the function type for the call method, otherwise | 31 /// defined, return the function type for the call method, otherwise |
| 41 /// return null. | 32 /// return null. |
| 42 FunctionType getCallMethodType(DartType t) { | 33 FunctionType getCallMethodType(DartType t) { |
| 43 if (t is InterfaceType) { | 34 if (t is InterfaceType) { |
| 44 ClassElement element = t.element; | 35 ClassElement element = t.element; |
| 45 InheritanceManager manager = new InheritanceManager(element.library); | 36 InheritanceManager manager = new InheritanceManager(element.library); |
| 46 FunctionType callType = manager.lookupMemberType(t, "call"); | 37 FunctionType callType = manager.lookupMemberType(t, "call"); |
| 47 return callType; | 38 return callType; |
| 48 } | 39 } |
| 49 return null; | 40 return null; |
| 50 } | 41 } |
| 51 | 42 |
| 52 /// Given an expression, return its type assuming it is | 43 /// Given an expression, return its type assuming it is |
| 53 /// in the caller position of a call (that is, accounting | 44 /// in the caller position of a call (that is, accounting |
| 54 /// for the possibility of a call method). Returns null | 45 /// for the possibility of a call method). Returns null |
| 55 /// if expression is not statically callable. | 46 /// if expression is not statically callable. |
| 56 FunctionType getTypeAsCaller(Expression applicand) { | 47 FunctionType getTypeAsCaller(Expression applicand) { |
| 57 var t = getStaticType(applicand); | 48 var t = getStaticType(applicand); |
| 58 if (t is InterfaceType) { | 49 if (t is InterfaceType) { |
| 59 return getCallMethodType(t); | 50 return getCallMethodType(t); |
| 60 } | 51 } |
| 61 if (t is FunctionType) return t; | 52 if (t is FunctionType) return t; |
| 62 return null; | 53 return null; |
| 63 } | 54 } |
| 64 | 55 |
| 65 DartType elementType(Element e); | |
| 66 | |
| 67 bool isDynamicTarget(Expression expr); | |
| 68 bool isDynamicCall(Expression call); | |
| 69 | |
| 70 /// Gets the expected return type of the given function [body], either from | 56 /// Gets the expected return type of the given function [body], either from |
| 71 /// a normal return/yield, or from a yield*. | 57 /// a normal return/yield, or from a yield*. |
| 72 DartType getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) { | 58 DartType getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) { |
| 73 FunctionType functionType; | 59 FunctionType functionType; |
| 74 var parent = body.parent; | 60 var parent = body.parent; |
| 75 if (parent is Declaration) { | 61 if (parent is Declaration) { |
| 76 functionType = elementType(parent.element); | 62 functionType = elementType(parent.element); |
| 77 } else { | 63 } else { |
| 78 assert(parent is FunctionExpression); | 64 assert(parent is FunctionExpression); |
| 79 functionType = getStaticType(parent); | 65 functionType = getStaticType(parent); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 } | 98 } |
| 113 if (type.isDynamic) { | 99 if (type.isDynamic) { |
| 114 return type; | 100 return type; |
| 115 } else if (type is InterfaceType && type.element == expectedType.element) { | 101 } else if (type is InterfaceType && type.element == expectedType.element) { |
| 116 return type.typeArguments[0]; | 102 return type.typeArguments[0]; |
| 117 } else { | 103 } else { |
| 118 // Malformed type - fallback on analyzer error. | 104 // Malformed type - fallback on analyzer error. |
| 119 return null; | 105 return null; |
| 120 } | 106 } |
| 121 } | 107 } |
| 122 } | |
| 123 | |
| 124 class RestrictedRules extends TypeRules { | |
| 125 final StrongModeOptions options; | |
| 126 DownwardsInference inferrer; | |
| 127 | |
| 128 RestrictedRules(TypeProvider provider, {this.options}) : super(provider) { | |
| 129 inferrer = new DownwardsInference(this); | |
| 130 } | |
| 131 | 108 |
| 132 DartType getStaticType(Expression expr) { | 109 DartType getStaticType(Expression expr) { |
| 133 return expr.staticType ?? provider.dynamicType; | 110 return expr.staticType ?? provider.dynamicType; |
| 134 } | 111 } |
| 135 | 112 |
| 136 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { | 113 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { |
| 137 if (t.isDynamic && dynamicIsBottom) return true; | 114 if (t.isDynamic && dynamicIsBottom) return true; |
| 138 // TODO(vsm): We need direct support for non-nullability in DartType. | 115 // TODO(vsm): We need direct support for non-nullability in DartType. |
| 139 // This should check on "true/nonnullable" Bottom | 116 // This should check on "true/nonnullable" Bottom |
| 140 if (t.isBottom) return true; | 117 if (t.isBottom) return true; |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 var entries = e.entries; | 725 var entries = e.entries; |
| 749 bool inferEntry(MapLiteralEntry entry) { | 726 bool inferEntry(MapLiteralEntry entry) { |
| 750 return _inferExpression(entry.key, kType, errors) && | 727 return _inferExpression(entry.key, kType, errors) && |
| 751 _inferExpression(entry.value, vType, errors); | 728 _inferExpression(entry.value, vType, errors); |
| 752 } | 729 } |
| 753 var b = entries.every(inferEntry); | 730 var b = entries.every(inferEntry); |
| 754 if (b) annotateMapLiteral(e, targs); | 731 if (b) annotateMapLiteral(e, targs); |
| 755 return b; | 732 return b; |
| 756 } | 733 } |
| 757 } | 734 } |
| OLD | NEW |