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 abstract 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 TypeRules(TypeProvider provider) |
22 : provider = provider, | 22 : provider = provider, |
23 objectMembers = utils.getObjectMemberMap(provider); | 23 objectMembers = utils.getObjectMemberMap(provider); |
24 | 24 |
25 MissingTypeReporter reportMissingType; | |
26 | |
27 bool isSubTypeOf(DartType t1, DartType t2); | 25 bool isSubTypeOf(DartType t1, DartType t2); |
28 bool isAssignable(DartType t1, DartType t2); | 26 bool isAssignable(DartType t1, DartType t2); |
29 | 27 |
30 bool isGroundType(DartType t) => true; | 28 bool isGroundType(DartType t) => true; |
31 // TODO(vsm): The default implementation is not ignoring the return type, | 29 // TODO(vsm): The default implementation is not ignoring the return type, |
32 // only the restricted override is. | 30 // only the restricted override is. |
33 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, | 31 bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2, |
34 {bool fuzzyArrows: true, bool ignoreReturn: false}) => | 32 {bool fuzzyArrows: true, bool ignoreReturn: false}) => |
35 isSubTypeOf(f1, f2); | 33 isSubTypeOf(f1, f2); |
36 | 34 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 return type; | 131 return type; |
134 } else if (type is InterfaceType && type.element == expectedType.element) { | 132 } else if (type is InterfaceType && type.element == expectedType.element) { |
135 return type.typeArguments[0]; | 133 return type.typeArguments[0]; |
136 } else { | 134 } else { |
137 // Malformed type - fallback on analyzer error. | 135 // Malformed type - fallback on analyzer error. |
138 return null; | 136 return null; |
139 } | 137 } |
140 } | 138 } |
141 } | 139 } |
142 | 140 |
143 // TODO(jmesserly): this is unused. | |
144 class DartRules extends TypeRules { | |
145 DartRules(TypeProvider provider) : super(provider); | |
146 | |
147 MissingTypeReporter reportMissingType = null; | |
148 | |
149 bool isSubTypeOf(DartType t1, DartType t2) { | |
150 return t1.isSubtypeOf(t2); | |
151 } | |
152 | |
153 bool isAssignable(DartType t1, DartType t2) { | |
154 return t1.isAssignableTo(t2); | |
155 } | |
156 | |
157 StaticInfo checkAssignment(Expression expr, DartType toType) { | |
158 final fromType = getStaticType(expr); | |
159 if (!isAssignable(fromType, toType)) { | |
160 return new StaticTypeError(this, expr, toType); | |
161 } | |
162 return null; | |
163 } | |
164 | |
165 DartType elementType(Element e) { | |
166 return (e as dynamic).type; | |
167 } | |
168 | |
169 /// By default, all invocations are dynamic in Dart. | |
170 bool isDynamic(DartType t) => true; | |
171 bool isDynamicTarget(Expression expr) => true; | |
172 bool isDynamicCall(Expression call) => true; | |
173 } | |
174 | |
175 typedef void MissingTypeReporter(Expression expr); | |
176 | |
177 class RestrictedRules extends TypeRules { | 141 class RestrictedRules extends TypeRules { |
178 MissingTypeReporter reportMissingType = null; | |
179 final StrongModeOptions options; | 142 final StrongModeOptions options; |
180 final List<DartType> _nonnullableTypes; | 143 final List<DartType> _nonnullableTypes; |
181 DownwardsInference inferrer; | 144 DownwardsInference inferrer; |
182 | 145 |
183 DartType _typeFromName(String name) { | 146 DartType _typeFromName(String name) { |
184 switch (name) { | 147 switch (name) { |
185 case 'int': | 148 case 'int': |
186 return provider.intType; | 149 return provider.intType; |
187 case 'double': | 150 case 'double': |
188 return provider.doubleType; | 151 return provider.doubleType; |
(...skipping 10 matching lines...) Expand all Loading... |
199 | 162 |
200 RestrictedRules(TypeProvider provider, {this.options}) | 163 RestrictedRules(TypeProvider provider, {this.options}) |
201 : _nonnullableTypes = <DartType>[], | 164 : _nonnullableTypes = <DartType>[], |
202 super(provider) { | 165 super(provider) { |
203 var types = options.nonnullableTypes; | 166 var types = options.nonnullableTypes; |
204 _nonnullableTypes.addAll(types.map(_typeFromName)); | 167 _nonnullableTypes.addAll(types.map(_typeFromName)); |
205 inferrer = new DownwardsInference(this); | 168 inferrer = new DownwardsInference(this); |
206 } | 169 } |
207 | 170 |
208 DartType getStaticType(Expression expr) { | 171 DartType getStaticType(Expression expr) { |
209 var type = expr.staticType; | 172 return expr.staticType ?? provider.dynamicType; |
210 if (type != null) return type; | |
211 if (reportMissingType != null) reportMissingType(expr); | |
212 return provider.dynamicType; | |
213 } | 173 } |
214 | 174 |
215 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { | 175 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { |
216 if (t.isDynamic && dynamicIsBottom) return true; | 176 if (t.isDynamic && dynamicIsBottom) return true; |
217 // TODO(vsm): We need direct support for non-nullability in DartType. | 177 // TODO(vsm): We need direct support for non-nullability in DartType. |
218 // This should check on "true/nonnullable" Bottom | 178 // This should check on "true/nonnullable" Bottom |
219 if (t.isBottom && _nonnullableTypes.isEmpty) return true; | 179 if (t.isBottom && _nonnullableTypes.isEmpty) return true; |
220 return false; | 180 return false; |
221 } | 181 } |
222 | 182 |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 var entries = e.entries; | 807 var entries = e.entries; |
848 bool inferEntry(MapLiteralEntry entry) { | 808 bool inferEntry(MapLiteralEntry entry) { |
849 return _inferExpression(entry.key, kType, errors) && | 809 return _inferExpression(entry.key, kType, errors) && |
850 _inferExpression(entry.value, vType, errors); | 810 _inferExpression(entry.value, vType, errors); |
851 } | 811 } |
852 var b = entries.every(inferEntry); | 812 var b = entries.every(inferEntry); |
853 if (b) annotateMapLiteral(e, targs); | 813 if (b) annotateMapLiteral(e, targs); |
854 return b; | 814 return b; |
855 } | 815 } |
856 } | 816 } |
OLD | NEW |