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

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

Issue 2743773004: Revert "Infer types of instance methods before any other inference." (Closed)
Patch Set: Created 3 years, 9 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
« no previous file with comments | « pkg/analyzer/lib/src/task/dart.dart ('k') | pkg/analyzer/test/src/task/strong_mode_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/visitor.dart'; 10 import 'package:analyzer/dart/ast/visitor.dart';
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 /** 67 /**
68 * The inheritance manager used to find overridden method. 68 * The inheritance manager used to find overridden method.
69 */ 69 */
70 final InheritanceManager inheritanceManager; 70 final InheritanceManager inheritanceManager;
71 71
72 /** 72 /**
73 * The classes that have been visited while attempting to infer the types of 73 * The classes that have been visited while attempting to infer the types of
74 * instance members of some base class. 74 * instance members of some base class.
75 */ 75 */
76 HashSet<ClassElementImpl> classesBeingInferred = 76 HashSet<ClassElementImpl> elementsBeingInferred =
77 new HashSet<ClassElementImpl>(); 77 new HashSet<ClassElementImpl>();
78 78
79 /** 79 /**
80 * Initialize a newly create inferrer. 80 * Initialize a newly create inferrer.
81 */ 81 */
82 InstanceMemberInferrer(TypeProvider typeProvider, this.inheritanceManager, 82 InstanceMemberInferrer(TypeProvider typeProvider, this.inheritanceManager,
83 {TypeSystem typeSystem}) 83 {TypeSystem typeSystem})
84 : typeSystem = (typeSystem != null) 84 : typeSystem = (typeSystem != null)
85 ? typeSystem 85 ? typeSystem
86 : new TypeSystemImpl(typeProvider), 86 : new TypeSystemImpl(typeProvider),
87 this.typeProvider = typeProvider; 87 this.typeProvider = typeProvider;
88 88
89 /** 89 /**
90 * Infer type information for all of the instance members in the given 90 * Infer type information for all of the instance members in the given
91 * compilation [unit]. 91 * compilation [unit].
92 */ 92 */
93 void inferCompilationUnit(CompilationUnitElement unit) { 93 void inferCompilationUnit(CompilationUnitElement unit) {
94 for (ClassElement classElement in unit.types) { 94 for (ClassElement classElement in unit.types) {
95 try { 95 try {
96 _inferClass(classElement); 96 _inferClass(classElement);
97 } on _CycleException { 97 } on _CycleException {
98 // This is a short circuit return to prevent types that inherit from 98 // This is a short circuit return to prevent types that inherit from
99 // types containing a circular reference from being inferred. 99 // types containing a circular reference from being inferred.
100 } 100 }
101 } 101 }
102 } 102 }
103 103
104 /** 104 /**
105 * Infer types for all of the instance methods in [unit].
106 */
107 void inferInstanceMethods(CompilationUnitElement unit) {
108 for (ClassElement classElement in unit.types) {
109 try {
110 _inferClassInstanceMethods(classElement);
111 } on _CycleException {}
112 }
113 }
114
115 /**
116 * Return `true` if the list of [elements] contains only methods. 105 * Return `true` if the list of [elements] contains only methods.
117 */ 106 */
118 bool _allSameElementKind( 107 bool _allSameElementKind(
119 ExecutableElement element, List<ExecutableElement> elements) { 108 ExecutableElement element, List<ExecutableElement> elements) {
120 return elements.every((e) => e.kind == element.kind); 109 return elements.every((e) => e.kind == element.kind);
121 } 110 }
122 111
123 /** 112 /**
124 * Compute the best type for the [parameter] at the given [index] that must be 113 * Compute the best type for the [parameter] at the given [index] that must be
125 * compatible with the types of the corresponding parameters of the given 114 * compatible with the types of the corresponding parameters of the given
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 196
208 /** 197 /**
209 * Infer type information for all of the instance members in the given 198 * Infer type information for all of the instance members in the given
210 * [classElement]. 199 * [classElement].
211 */ 200 */
212 void _inferClass(ClassElement classElement) { 201 void _inferClass(ClassElement classElement) {
213 if (classElement is ClassElementImpl) { 202 if (classElement is ClassElementImpl) {
214 if (classElement.hasBeenInferred) { 203 if (classElement.hasBeenInferred) {
215 return; 204 return;
216 } 205 }
217 if (!classesBeingInferred.add(classElement)) { 206 if (!elementsBeingInferred.add(classElement)) {
218 // We have found a circularity in the class hierarchy. For now we just 207 // We have found a circularity in the class hierarchy. For now we just
219 // stop trying to infer any type information for any classes that 208 // stop trying to infer any type information for any classes that
220 // inherit from any class in the cycle. We could potentially limit the 209 // inherit from any class in the cycle. We could potentially limit the
221 // algorithm to only not inferring types in the classes in the cycle, 210 // algorithm to only not inferring types in the classes in the cycle,
222 // but it isn't clear that the results would be significantly better. 211 // but it isn't clear that the results would be significantly better.
223 throw new _CycleException(); 212 throw new _CycleException();
224 } 213 }
225 try { 214 try {
226 // 215 //
227 // Ensure that all of instance members in the supertypes have had types 216 // Ensure that all of instance members in the supertypes have had types
228 // inferred for them. 217 // inferred for them.
229 // 218 //
230 _inferType(classElement.supertype); 219 _inferType(classElement.supertype);
231 classElement.mixins.forEach(_inferType); 220 classElement.mixins.forEach(_inferType);
232 classElement.interfaces.forEach(_inferType); 221 classElement.interfaces.forEach(_inferType);
233 // 222 //
234 // Then infer the types for the members. 223 // Then infer the types for the members.
235 // 224 //
236 classElement.fields.forEach(_inferField); 225 classElement.fields.forEach(_inferField);
237 classElement.accessors.forEach(_inferExecutable); 226 classElement.accessors.forEach(_inferExecutable);
227 classElement.methods.forEach(_inferExecutable);
238 // 228 //
239 // Infer initializing formal parameter types. This must happen after 229 // Infer initializing formal parameter types. This must happen after
240 // field types are inferred. 230 // field types are inferred.
241 // 231 //
242 classElement.constructors.forEach(_inferConstructorFieldFormals); 232 classElement.constructors.forEach(_inferConstructorFieldFormals);
243 classElement.hasBeenInferred = true; 233 classElement.hasBeenInferred = true;
244 } finally { 234 } finally {
245 classesBeingInferred.remove(classElement); 235 elementsBeingInferred.remove(classElement);
246 } 236 }
247 } 237 }
248 } 238 }
249
250 /**
251 * Infer types for all of the instance methods in the given [classElement].
252 */
253 void _inferClassInstanceMethods(ClassElement classElement) {
254 if (classElement is ClassElementImpl) {
255 if (classElement.hasInferredInstanceMethods) {
256 return;
257 }
258 if (!classesBeingInferred.add(classElement)) {
259 // We have found a circularity in the class hierarchy. For now we just
260 // stop trying to infer any type information for any classes that
261 // inherit from any class in the cycle. We could potentially limit the
262 // algorithm to only not inferring types in the classes in the cycle,
263 // but it isn't clear that the results would be significantly better.
264 throw new _CycleException();
265 }
266 try {
267 //
268 // Process supertypes first.
269 //
270 void processSupertype(InterfaceType type) {
271 ClassElement element = type?.element;
272 if (element != null) {
273 _inferClassInstanceMethods(element);
274 }
275 }
276
277 processSupertype(classElement.supertype);
278 classElement.mixins.forEach(processSupertype);
279 classElement.interfaces.forEach(processSupertype);
280
281 //
282 // Then infer the types for the instance methods in this class.
283 //
284 classElement.methods.forEach(_inferExecutable);
285 classElement.hasInferredInstanceMethods = true;
286 } finally {
287 classesBeingInferred.remove(classElement);
288 }
289 }
290 }
291 239
292 void _inferConstructorFieldFormals(ConstructorElement element) { 240 void _inferConstructorFieldFormals(ConstructorElement element) {
293 for (ParameterElement p in element.parameters) { 241 for (ParameterElement p in element.parameters) {
294 if (p is FieldFormalParameterElementImpl) { 242 if (p is FieldFormalParameterElementImpl) {
295 _inferFieldFormalParameter(p); 243 _inferFieldFormalParameter(p);
296 } 244 }
297 } 245 }
298 } 246 }
299 247
300 /** 248 /**
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 results.add(element); 498 results.add(element);
551 } 499 }
552 } 500 }
553 } 501 }
554 } 502 }
555 503
556 /** 504 /**
557 * A class of exception that is not used anywhere else. 505 * A class of exception that is not used anywhere else.
558 */ 506 */
559 class _CycleException implements Exception {} 507 class _CycleException implements Exception {}
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/task/dart.dart ('k') | pkg/analyzer/test/src/task/strong_mode_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698