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 /// Encapsulates how to invoke the analyzer resolver and overrides how it | 5 /// Encapsulates how to invoke the analyzer resolver and overrides how it |
6 /// computes types on expressions to use our restricted set of types. | 6 /// computes types on expressions to use our restricted set of types. |
7 library dev_compiler.src.checker.resolver; | 7 library dev_compiler.src.checker.resolver; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 } | 161 } |
162 | 162 |
163 if (_options.inferFromOverrides) { | 163 if (_options.inferFromOverrides) { |
164 // Infer field types from overrides first, otherwise from initializers. | 164 // Infer field types from overrides first, otherwise from initializers. |
165 var pending = new Set<VariableDeclaration>(); | 165 var pending = new Set<VariableDeclaration>(); |
166 cls.members | 166 cls.members |
167 .where(_isInstanceField) | 167 .where(_isInstanceField) |
168 .forEach((f) => _inferFieldTypeFromOverride(f, pending)); | 168 .forEach((f) => _inferFieldTypeFromOverride(f, pending)); |
169 if (pending.isNotEmpty) _inferVariableFromInitializer(pending); | 169 if (pending.isNotEmpty) _inferVariableFromInitializer(pending); |
170 | 170 |
171 // Infer return-types from overrides | 171 // Infer return-types and param-types from overrides |
172 cls.members | 172 cls.members |
173 .where((m) => m is MethodDeclaration && !m.isStatic) | 173 .where((m) => m is MethodDeclaration && !m.isStatic) |
174 .forEach(_inferMethodReturnTypeFromOverride); | 174 .forEach(_inferMethodTypesFromOverride); |
175 } else { | 175 } else { |
176 _inferVariableFromInitializer(cls.members | 176 _inferVariableFromInitializer(cls.members |
177 .where(_isInstanceField) | 177 .where(_isInstanceField) |
178 .expand((f) => f.fields.variables)); | 178 .expand((f) => f.fields.variables)); |
179 } | 179 } |
180 } | 180 } |
181 classes.forEach(visit); | 181 classes.forEach(visit); |
182 } | 182 } |
183 | 183 |
184 void _reanalyzeVar(Map<Source, RestrictedResolverVisitor> visitors, | 184 void _reanalyzeVar(Map<Source, RestrictedResolverVisitor> visitors, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 } | 224 } |
225 | 225 |
226 // Use type from the override. | 226 // Use type from the override. |
227 var newType = type.returnType; | 227 var newType = type.returnType; |
228 varElement.type = newType; | 228 varElement.type = newType; |
229 varElement.getter.returnType = newType; | 229 varElement.getter.returnType = newType; |
230 if (!varElement.isFinal) varElement.setter.parameters[0].type = newType; | 230 if (!varElement.isFinal) varElement.setter.parameters[0].type = newType; |
231 } | 231 } |
232 } | 232 } |
233 | 233 |
234 void _inferMethodReturnTypeFromOverride(MethodDeclaration method) { | 234 void _inferMethodTypesFromOverride(MethodDeclaration method) { |
235 var methodElement = method.element; | 235 var methodElement = method.element; |
236 if ((methodElement is MethodElement || | 236 if (methodElement is! MethodElement && |
237 methodElement is PropertyAccessorElement) && | 237 methodElement is! PropertyAccessorElement) return; |
238 methodElement.returnType.isDynamic && | 238 |
239 method.returnType == null) { | 239 var enclosingElement = methodElement.enclosingElement as ClassElement; |
240 var enclosingElement = methodElement.enclosingElement as ClassElement; | 240 FunctionType type = |
241 var type = searchTypeFor(enclosingElement.type, methodElement); | 241 null; // searchTypeFor(enclosingElement.type, methodElement); |
242 | |
243 // Infer the return type if omitted | |
244 if (methodElement.returnType.isDynamic && method.returnType == null) { | |
245 type = searchTypeFor(enclosingElement.type, methodElement); | |
242 if (type != null && !type.returnType.isDynamic) { | 246 if (type != null && !type.returnType.isDynamic) { |
243 methodElement.returnType = type.returnType; | 247 methodElement.returnType = type.returnType; |
244 } | 248 } |
245 } | 249 } |
250 | |
251 // Infer parameter types if omitted | |
Brian Wilkerson
2015/08/25 14:06:29
In the ported version of the code we get all of th
vsm
2015/08/25 15:43:47
Perhaps we should do equality for params as well t
Brian Wilkerson
2015/08/25 15:54:51
For the return type we'd need a greatest lower bou
Leaf
2015/08/25 17:03:50
I think equality is fine for now. For return type
| |
252 if (method.parameters == null) return; | |
253 var parameters = method.parameters.parameters; | |
254 var length = parameters.length; | |
255 for (int i = 0; i < length; ++i) { | |
256 var parameter = parameters[i]; | |
257 if (parameter is SimpleFormalParameter && parameter.type == null) { | |
258 type = type ?? searchTypeFor(enclosingElement.type, methodElement); | |
Brian Wilkerson
2015/08/25 14:06:29
I can't say I'm fond of the lazy initialization te
vsm
2015/08/25 15:43:47
Yes, it looks like a fairly expensive operation th
| |
259 if (type != null && | |
260 type.parameters.length > i && | |
261 !type.parameters[i].type.isDynamic) { | |
262 parameter.element.type = type.parameters[i].type; | |
263 } | |
264 } | |
265 } | |
246 } | 266 } |
247 | 267 |
248 void _inferVariableFromInitializer(Iterable<VariableDeclaration> variables) { | 268 void _inferVariableFromInitializer(Iterable<VariableDeclaration> variables) { |
249 for (var variable in variables) { | 269 for (var variable in variables) { |
250 var declaration = variable.parent as VariableDeclarationList; | 270 var declaration = variable.parent as VariableDeclarationList; |
251 // Only infer on variables that don't have any declared type. | 271 // Only infer on variables that don't have any declared type. |
252 if (declaration.type != null) continue; | 272 if (declaration.type != null) continue; |
253 if (_options.onlyInferConstsAndFinalFields && | 273 if (_options.onlyInferConstsAndFinalFields && |
254 !declaration.isFinal && | 274 !declaration.isFinal && |
255 !declaration.isConst) { | 275 !declaration.isConst) { |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
716 } | 736 } |
717 } | 737 } |
718 | 738 |
719 // Review note: no longer need to override visitFunctionExpression, this is | 739 // Review note: no longer need to override visitFunctionExpression, this is |
720 // handled by the analyzer internally. | 740 // handled by the analyzer internally. |
721 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result? | 741 // TODO(vsm): in visitbinaryExpression: check computeStaticReturnType result? |
722 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression | 742 // TODO(vsm): in visitFunctionDeclaration: Should we ever use the expression |
723 // type in a (...) => expr or just the written type? | 743 // type in a (...) => expr or just the written type? |
724 | 744 |
725 } | 745 } |
OLD | NEW |