Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(518)

Side by Side Diff: pkg/analyzer/lib/src/task/strong_mode.dart

Issue 1323653002: Task to infer static variables (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 analyzer.src.task.strong_mode; 5 library analyzer.src.task.strong_mode;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/src/generated/ast.dart'; 9 import 'package:analyzer/src/generated/ast.dart';
10 import 'package:analyzer/src/generated/element.dart'; 10 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/engine.dart';
12 import 'package:analyzer/src/generated/java_engine.dart';
13 import 'package:analyzer/src/generated/resolver.dart'; 11 import 'package:analyzer/src/generated/resolver.dart';
14 import 'package:analyzer/src/generated/utilities_dart.dart'; 12 import 'package:analyzer/src/generated/utilities_dart.dart';
15 13
16 /** 14 /**
15 * Set the type of the sole parameter of the given [element] to the given [type] .
16 */
17 void setParameterType(PropertyAccessorElement element, DartType type) {
18 if (element is PropertyAccessorElementImpl) {
Paul Berry 2015/08/29 01:14:55 I realize this is just code motion, so feel free t
Brian Wilkerson 2015/08/31 15:08:52 Each of the 'if' statements in these methods is th
Paul Berry 2015/08/31 15:50:59 I understand that. I am not suggesting replacing
Brian Wilkerson 2015/08/31 18:35:38 While I understand the testing value, I really don
19 ParameterElement parameter = _getParameter(element);
20 if (parameter is ParameterElementImpl) {
21 //
22 // Update the type of the parameter.
23 //
24 parameter.type = type;
25 //
26 // Update the type of the setter to reflect the new parameter type.
27 //
28 FunctionType functionType = element.type;
29 if (functionType is FunctionTypeImpl) {
30 element.type =
31 new FunctionTypeImpl(element, functionType.prunedTypedefs);
32 }
33 }
34 }
35 }
36
37 /**
38 * Set the return type of the given [element] to the given [type].
39 */
40 void setReturnType(ExecutableElement element, DartType type) {
41 if (element is ExecutableElementImpl) {
Paul Berry 2015/08/29 01:14:55 Similar concerns in this function.
42 //
43 // Update the return type of the element, which is stored in two places:
44 // directly in the element and indirectly in the type of the element.
45 //
46 element.returnType = type;
47 FunctionType functionType = element.type;
48 if (functionType is FunctionTypeImpl) {
49 element.type = new FunctionTypeImpl(element, functionType.prunedTypedefs);
50 }
51 }
52 }
53
54 /**
55 * Return the element for the single parameter of the given [setter], or `null`
56 * if the executable element is not a setter or does not have a single
57 * parameter.
58 */
59 ParameterElement _getParameter(ExecutableElement setter) {
60 if (setter is PropertyAccessorElement && setter.isSetter) {
61 List<ParameterElement> parameters = setter.parameters;
62 if (parameters.length == 1) {
63 return parameters[0];
64 }
65 }
66 return null;
67 }
68
69 /**
17 * A function that returns `true` if the given [variable] passes the filter. 70 * A function that returns `true` if the given [variable] passes the filter.
18 */ 71 */
19 typedef bool VariableFilter(VariableElement element); 72 typedef bool VariableFilter(VariableElement element);
20 73
21 /** 74 /**
22 * An object used to find static variables whose types should be inferred and 75 * An object used to find static variables whose types should be inferred and
23 * classes whose members should have types inferred. Clients are expected to 76 * classes whose members should have types inferred. Clients are expected to
24 * visit a [CompilationUnit]. 77 * visit a [CompilationUnit].
25 */ 78 */
26 class InferrenceFinder extends SimpleAstVisitor { 79 class InferrenceFinder extends SimpleAstVisitor {
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 DartType type = _getReturnType(overriddenMethods[i]); 239 DartType type = _getReturnType(overriddenMethods[i]);
187 if (returnType == null) { 240 if (returnType == null) {
188 returnType = type; 241 returnType = type;
189 } else if (returnType != type) { 242 } else if (returnType != type) {
190 return typeProvider.dynamicType; 243 return typeProvider.dynamicType;
191 } 244 }
192 } 245 }
193 return returnType == null ? typeProvider.dynamicType : returnType; 246 return returnType == null ? typeProvider.dynamicType : returnType;
194 } 247 }
195 248
196 /**
197 * Return the element for the single parameter of the given [setter], or
198 * `null` if the executable element is not a setter or does not have a single
199 * parameter.
200 */
201 ParameterElement _getParameter(ExecutableElement setter) {
202 if (setter is PropertyAccessorElement && setter.isSetter) {
203 List<ParameterElement> parameters = setter.parameters;
204 if (parameters.length == 1) {
205 return parameters[0];
206 }
207 }
208 return null;
209 }
210
211 DartType _getReturnType(ExecutableElement element) { 249 DartType _getReturnType(ExecutableElement element) {
212 DartType returnType = element.returnType; 250 DartType returnType = element.returnType;
213 if (returnType == null) { 251 if (returnType == null) {
214 return typeProvider.dynamicType; 252 return typeProvider.dynamicType;
215 } 253 }
216 return returnType; 254 return returnType;
217 } 255 }
218 256
219 /** 257 /**
220 * Given a [method], return the type of the parameter in the method that 258 * Given a [method], return the type of the parameter in the method that
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 .lookupOverrides( 315 .lookupOverrides(
278 accessorElement.enclosingElement, accessorElement.name + '='); 316 accessorElement.enclosingElement, accessorElement.name + '=');
279 PropertyAccessorElement setter = (accessorElement.enclosingElement 317 PropertyAccessorElement setter = (accessorElement.enclosingElement
280 as ClassElement).getSetter(accessorElement.name); 318 as ClassElement).getSetter(accessorElement.name);
281 if (setter != null) { 319 if (setter != null) {
282 overriddenSetters.add(setter); 320 overriddenSetters.add(setter);
283 } 321 }
284 if (!_isCompatible(newType, overriddenSetters)) { 322 if (!_isCompatible(newType, overriddenSetters)) {
285 newType = typeProvider.dynamicType; 323 newType = typeProvider.dynamicType;
286 } 324 }
287 _setReturnType(accessorElement, newType); 325 setReturnType(accessorElement, newType);
288 (accessorElement.variable as FieldElementImpl).type = newType; 326 (accessorElement.variable as FieldElementImpl).type = newType;
289 } 327 }
290 } 328 }
291 } 329 }
292 330
293 /** 331 /**
294 * Infer type information for all of the instance members in the given 332 * Infer type information for all of the instance members in the given
295 * [classElement]. 333 * [classElement].
296 */ 334 */
297 void _inferClass(ClassElement classElement) { 335 void _inferClass(ClassElement classElement) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 if (newType == null) { 396 if (newType == null) {
359 if (fieldElement.initializer != null && 397 if (fieldElement.initializer != null &&
360 (fieldElement.isFinal || overriddenGetters.isEmpty)) { 398 (fieldElement.isFinal || overriddenGetters.isEmpty)) {
361 newType = fieldElement.initializer.returnType; 399 newType = fieldElement.initializer.returnType;
362 } 400 }
363 } 401 }
364 if (newType == null || newType.isBottom) { 402 if (newType == null || newType.isBottom) {
365 newType = typeProvider.dynamicType; 403 newType = typeProvider.dynamicType;
366 } 404 }
367 (fieldElement as FieldElementImpl).type = newType; 405 (fieldElement as FieldElementImpl).type = newType;
368 _setReturnType(fieldElement.getter, newType); 406 setReturnType(fieldElement.getter, newType);
369 _setParameterType(fieldElement.setter, newType); 407 setParameterType(fieldElement.setter, newType);
370 } 408 }
371 } 409 }
372 410
373 /** 411 /**
374 * If the given [methodElement] represents a non-synthetic instance method 412 * If the given [methodElement] represents a non-synthetic instance method
375 * for which no return type was provided, infer the return type of the method. 413 * for which no return type was provided, infer the return type of the method.
376 */ 414 */
377 void _inferMethod(MethodElement methodElement) { 415 void _inferMethod(MethodElement methodElement) {
378 if (methodElement.isSynthetic || methodElement.isStatic) { 416 if (methodElement.isSynthetic || methodElement.isStatic) {
379 return; 417 return;
380 } 418 }
381 List<ExecutableElement> overriddenMethods = null; 419 List<ExecutableElement> overriddenMethods = null;
382 // 420 //
383 // Infer the return type. 421 // Infer the return type.
384 // 422 //
385 if (methodElement.hasImplicitReturnType) { 423 if (methodElement.hasImplicitReturnType) {
386 overriddenMethods = inheritanceManager.lookupOverrides( 424 overriddenMethods = inheritanceManager.lookupOverrides(
387 methodElement.enclosingElement, methodElement.name); 425 methodElement.enclosingElement, methodElement.name);
388 if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) { 426 if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) {
389 return; 427 return;
390 } 428 }
391 MethodElementImpl element = methodElement as MethodElementImpl; 429 MethodElementImpl element = methodElement as MethodElementImpl;
392 _setReturnType(element, _computeReturnType(overriddenMethods)); 430 setReturnType(element, _computeReturnType(overriddenMethods));
393 } 431 }
394 // 432 //
395 // Infer the parameter types. 433 // Infer the parameter types.
396 // 434 //
397 List<ParameterElement> parameters = methodElement.parameters; 435 List<ParameterElement> parameters = methodElement.parameters;
398 var length = parameters.length; 436 var length = parameters.length;
399 for (int i = 0; i < length; ++i) { 437 for (int i = 0; i < length; ++i) {
400 ParameterElement parameter = parameters[i]; 438 ParameterElement parameter = parameters[i];
401 if (parameter is ParameterElementImpl && parameter.hasImplicitType) { 439 if (parameter is ParameterElementImpl && parameter.hasImplicitType) {
402 overriddenMethods = overriddenMethods ?? 440 overriddenMethods = overriddenMethods ??
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 * Return `true` if the list of [elements] contains only methods. 491 * Return `true` if the list of [elements] contains only methods.
454 */ 492 */
455 bool _onlyMethods(List<ExecutableElement> elements) { 493 bool _onlyMethods(List<ExecutableElement> elements) {
456 for (ExecutableElement element in elements) { 494 for (ExecutableElement element in elements) {
457 if (element is! MethodElement) { 495 if (element is! MethodElement) {
458 return false; 496 return false;
459 } 497 }
460 } 498 }
461 return true; 499 return true;
462 } 500 }
463
464 /**
465 * Set the type of the sole parameter of the given [element] to the given [typ e].
466 */
467 void _setParameterType(PropertyAccessorElement element, DartType type) {
468 if (element is PropertyAccessorElementImpl) {
469 ParameterElement parameter = _getParameter(element);
470 if (parameter is ParameterElementImpl) {
471 //
472 // Update the type of the parameter.
473 //
474 parameter.type = type;
475 //
476 // Update the type of the setter to reflect the new parameter type.
477 //
478 FunctionType functionType = element.type;
479 if (functionType is FunctionTypeImpl) {
480 element.type =
481 new FunctionTypeImpl(element, functionType.prunedTypedefs);
482 }
483 }
484 }
485 }
486
487 /**
488 * Set the return type of the given [element] to the given [type].
489 */
490 void _setReturnType(ExecutableElement element, DartType type) {
491 if (element is ExecutableElementImpl) {
492 //
493 // Update the return type of the element, which is stored in two places:
494 // directly in the element and indirectly in the type of the element.
495 //
496 element.returnType = type;
497 FunctionType functionType = element.type;
498 if (functionType is FunctionTypeImpl) {
499 element.type =
500 new FunctionTypeImpl(element, functionType.prunedTypedefs);
501 }
502 }
503 }
504 } 501 }
505 502
506 /** 503 /**
507 * A visitor that will gather all of the variables referenced within a given 504 * A visitor that will gather all of the variables referenced within a given
508 * AST structure. The collection can be restricted to contain only those 505 * AST structure. The collection can be restricted to contain only those
509 * variables that pass a specified filter. 506 * variables that pass a specified filter.
510 */ 507 */
511 class VariableGatherer extends RecursiveAstVisitor { 508 class VariableGatherer extends RecursiveAstVisitor {
512 /** 509 /**
513 * The filter used to limit which variables are gathered, or `null` if no 510 * The filter used to limit which variables are gathered, or `null` if no
(...skipping 23 matching lines...) Expand all
537 results.add(element); 534 results.add(element);
538 } 535 }
539 } 536 }
540 } 537 }
541 } 538 }
542 539
543 /** 540 /**
544 * A class of exception that is not used anywhere else. 541 * A class of exception that is not used anywhere else.
545 */ 542 */
546 class _CycleException implements Exception {} 543 class _CycleException implements Exception {}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698