| 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 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'; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 } | 76 } |
| 77 return null; | 77 return null; |
| 78 } | 78 } |
| 79 | 79 |
| 80 /** | 80 /** |
| 81 * A function that returns `true` if the given [variable] passes the filter. | 81 * A function that returns `true` if the given [variable] passes the filter. |
| 82 */ | 82 */ |
| 83 typedef bool VariableFilter(VariableElement element); | 83 typedef bool VariableFilter(VariableElement element); |
| 84 | 84 |
| 85 /** | 85 /** |
| 86 * An object used to find static variables whose types should be inferred and | |
| 87 * classes whose members should have types inferred. Clients are expected to | |
| 88 * visit a [CompilationUnit]. | |
| 89 */ | |
| 90 class InferrenceFinder extends SimpleAstVisitor { | |
| 91 /** | |
| 92 * The static variables that should have types inferred for them. | |
| 93 */ | |
| 94 final List<VariableElement> staticVariables = <VariableElement>[]; | |
| 95 | |
| 96 /** | |
| 97 * The classes defined in the unit. | |
| 98 * | |
| 99 * TODO(brianwilkerson) We don't currently remove classes whose members do not | |
| 100 * need to be processed, but we potentially could. | |
| 101 */ | |
| 102 final List<ClassElement> classes = <ClassElement>[]; | |
| 103 | |
| 104 /** | |
| 105 * Initialize a newly created finder. | |
| 106 */ | |
| 107 InferrenceFinder(); | |
| 108 | |
| 109 @override | |
| 110 void visitClassDeclaration(ClassDeclaration node) { | |
| 111 classes.add(node.element); | |
| 112 for (ClassMember member in node.members) { | |
| 113 member.accept(this); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 @override | |
| 118 void visitClassTypeAlias(ClassTypeAlias node) { | |
| 119 classes.add(node.element); | |
| 120 } | |
| 121 | |
| 122 @override | |
| 123 void visitCompilationUnit(CompilationUnit node) { | |
| 124 for (CompilationUnitMember declaration in node.declarations) { | |
| 125 declaration.accept(this); | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 @override | |
| 130 void visitFieldDeclaration(FieldDeclaration node) { | |
| 131 if (node.isStatic && node.fields.type == null) { | |
| 132 _addVariables(node.fields.variables); | |
| 133 } | |
| 134 } | |
| 135 | |
| 136 @override | |
| 137 void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | |
| 138 if (node.variables.type == null) { | |
| 139 _addVariables(node.variables.variables); | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 /** | |
| 144 * Add all of the [variables] with initializers to the list of variables whose | |
| 145 * type can be inferred. Technically, we only infer the types of variables | |
| 146 * that do not have a static type, but all variables with initializers | |
| 147 * potentially need to be re-resolved after inference because they might | |
| 148 * refer to fields whose type was inferred. | |
| 149 */ | |
| 150 void _addVariables(NodeList<VariableDeclaration> variables) { | |
| 151 for (VariableDeclaration variable in variables) { | |
| 152 if (variable.initializer != null) { | |
| 153 VariableElement element = variable.element; | |
| 154 if (element.hasImplicitType) { | |
| 155 staticVariables.add(element); | |
| 156 } | |
| 157 } | |
| 158 } | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 /** | |
| 163 * An object used to infer the type of instance fields and the return types of | 86 * An object used to infer the type of instance fields and the return types of |
| 164 * instance methods within a single compilation unit. | 87 * instance methods within a single compilation unit. |
| 165 */ | 88 */ |
| 166 class InstanceMemberInferrer { | 89 class InstanceMemberInferrer { |
| 167 /** | 90 /** |
| 168 * The type provider used to look up types. | 91 * The type provider used to look up types. |
| 169 */ | 92 */ |
| 170 final TypeProvider typeProvider; | 93 final TypeProvider typeProvider; |
| 171 | 94 |
| 172 /** | 95 /** |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 (fieldElement.isFinal || overriddenGetters.isEmpty)) { | 332 (fieldElement.isFinal || overriddenGetters.isEmpty)) { |
| 410 newType = fieldElement.initializer.returnType; | 333 newType = fieldElement.initializer.returnType; |
| 411 } | 334 } |
| 412 } | 335 } |
| 413 if (newType == null || newType.isBottom) { | 336 if (newType == null || newType.isBottom) { |
| 414 newType = typeProvider.dynamicType; | 337 newType = typeProvider.dynamicType; |
| 415 } | 338 } |
| 416 (fieldElement as FieldElementImpl).type = newType; | 339 (fieldElement as FieldElementImpl).type = newType; |
| 417 setReturnType(fieldElement.getter, newType); | 340 setReturnType(fieldElement.getter, newType); |
| 418 if (!fieldElement.isFinal && !fieldElement.isConst) { | 341 if (!fieldElement.isFinal && !fieldElement.isConst) { |
| 419 setParameterType(fieldElement.setter, newType); | 342 setParameterType(fieldElement.setter, newType); |
| 420 } | 343 } |
| 421 } | 344 } |
| 422 } | 345 } |
| 423 | 346 |
| 424 /** | 347 /** |
| 425 * If the given [methodElement] represents a non-synthetic instance method | 348 * If the given [methodElement] represents a non-synthetic instance method |
| 426 * for which no return type was provided, infer the return type of the method. | 349 * for which no return type was provided, infer the return type of the method. |
| 427 */ | 350 */ |
| 428 void _inferMethod(MethodElement methodElement) { | 351 void _inferMethod(MethodElement methodElement) { |
| 429 if (methodElement.isSynthetic || methodElement.isStatic) { | 352 if (methodElement.isSynthetic || methodElement.isStatic) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 results.add(element); | 471 results.add(element); |
| 549 } | 472 } |
| 550 } | 473 } |
| 551 } | 474 } |
| 552 } | 475 } |
| 553 | 476 |
| 554 /** | 477 /** |
| 555 * A class of exception that is not used anywhere else. | 478 * A class of exception that is not used anywhere else. |
| 556 */ | 479 */ |
| 557 class _CycleException implements Exception {} | 480 class _CycleException implements Exception {} |
| OLD | NEW |