Skip to content

Commit cd36725

Browse files
scheglovCommit Queue
authored andcommitted
Elements. Track not yet inferred classes in a set in InstanceMemberInferrer instead of a field in InterfaceElementImpl.
Change-Id: I3cf6962813d1e62e7b0caaa5e0a2cd9601e26781 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448243 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 7914ee2 commit cd36725

File tree

3 files changed

+40
-77
lines changed

3 files changed

+40
-77
lines changed

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4629,10 +4629,6 @@ abstract class InterfaceElementImpl extends InstanceElementImpl
46294629
List<InterfaceTypeImpl>? Function(InterfaceElementImpl)?
46304630
mixinInferenceCallback;
46314631

4632-
/// A flag indicating whether the types associated with the instance members
4633-
/// of this class have been inferred.
4634-
bool hasBeenInferred = false;
4635-
46364632
/// Whether the class or its superclass declares a non-final instance field.
46374633
bool hasNonFinalField = false;
46384634

pkg/analyzer/lib/src/summary2/instance_member_inferrer.dart

Lines changed: 35 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import 'package:collection/collection.dart';
1818
/// https://github.com/dart-lang/language/blob/main/resources/type-system/inference.md
1919
class InstanceMemberInferrer {
2020
final InheritanceManager3 inheritance;
21-
final Set<InterfaceElementImpl> elementsBeingInferred = {};
21+
final Set<InterfaceElementImpl> interfacesToInfer = {};
2222

2323
late InterfaceElementImpl currentInterfaceElement;
2424

@@ -29,11 +29,11 @@ class InstanceMemberInferrer {
2929
return currentInterfaceElement.library.typeSystem;
3030
}
3131

32-
void inferLibrary(LibraryElementImpl library) {
33-
_inferClasses(library.classes);
34-
_inferClasses(library.enums);
35-
_inferExtensionTypes(library.extensionTypes);
36-
_inferClasses(library.mixins);
32+
void perform(List<InterfaceElementImpl> elements) {
33+
interfacesToInfer.addAll(elements);
34+
for (var element in elements) {
35+
_inferClass(element);
36+
}
3737
}
3838

3939
/// Return `true` if the elements corresponding to the [elements] have the
@@ -317,67 +317,43 @@ class InstanceMemberInferrer {
317317
/// Infer type information for all of the instance members in the given
318318
/// [element].
319319
void _inferClass(InterfaceElementImpl element) {
320-
if (element.hasBeenInferred) {
320+
if (!interfacesToInfer.remove(element)) {
321321
return;
322322
}
323323

324324
_setInducedModifier(element);
325325

326-
if (!elementsBeingInferred.add(element)) {
327-
// We have found a circularity in the class hierarchy. For now we just
328-
// stop trying to infer any type information for any classes that
329-
// inherit from any class in the cycle. We could potentially limit the
330-
// algorithm to only not inferring types in the classes in the cycle,
331-
// but it isn't clear that the results would be significantly better.
332-
throw _CycleException();
333-
}
326+
//
327+
// Ensure that all of instance members in the supertypes have had types
328+
// inferred for them.
329+
//
330+
_inferType(element.supertype);
331+
element.mixins.forEach(_inferType);
332+
element.interfaces.forEach(_inferType);
334333

335-
try {
336-
//
337-
// Ensure that all of instance members in the supertypes have had types
338-
// inferred for them.
339-
//
340-
_inferType(element.supertype);
341-
element.mixins.forEach(_inferType);
342-
element.interfaces.forEach(_inferType);
343-
//
344-
// Then infer the types for the members.
345-
//
346-
// TODO(scheglov): get other members from the container
347-
currentInterfaceElement = element;
348-
for (var field in element.fields) {
349-
_inferAccessorOrField(field: field);
350-
}
351-
for (var getter in element.getters) {
352-
_inferAccessorOrField(getter: getter);
353-
}
354-
for (var setter in element.setters) {
355-
_inferAccessorOrField(setter: setter);
356-
}
357-
for (var method in element.methods) {
358-
_inferExecutable(method);
359-
}
360-
//
361-
// Infer initializing formal parameter types. This must happen after
362-
// field types are inferred.
363-
//
364-
for (var constructor in element.constructors) {
365-
_inferConstructor(constructor);
366-
}
367-
element.hasBeenInferred = true;
368-
} finally {
369-
elementsBeingInferred.remove(element);
334+
//
335+
// Then infer the types for the members.
336+
//
337+
currentInterfaceElement = element;
338+
for (var field in element.fields) {
339+
_inferAccessorOrField(field: field);
340+
}
341+
for (var getter in element.getters) {
342+
_inferAccessorOrField(getter: getter);
343+
}
344+
for (var setter in element.setters) {
345+
_inferAccessorOrField(setter: setter);
346+
}
347+
for (var method in element.methods) {
348+
_inferExecutable(method);
370349
}
371-
}
372350

373-
void _inferClasses(List<InterfaceElementImpl> elements) {
374-
for (var element in elements) {
375-
try {
376-
_inferClass(element);
377-
} on _CycleException {
378-
// This is a short circuit return to prevent types that inherit from
379-
// types containing a circular reference from being inferred.
380-
}
351+
//
352+
// Infer initializing formal parameter types. This must happen after
353+
// field types are inferred.
354+
//
355+
for (var constructor in element.constructors) {
356+
_inferConstructor(constructor);
381357
}
382358
}
383359

@@ -494,14 +470,6 @@ class InstanceMemberInferrer {
494470
_resetOperatorEqualParameterTypeToDynamic(element, overriddenElements);
495471
}
496472

497-
void _inferExtensionTypes(List<ExtensionTypeElementImpl> extensionTypes) {
498-
for (var extensionType in extensionTypes) {
499-
for (var constructor in extensionType.constructors) {
500-
_inferConstructor(constructor);
501-
}
502-
}
503-
}
504-
505473
void _inferMixinApplicationConstructor(
506474
ClassElementImpl classElement,
507475
ConstructorElementImpl constructor,
@@ -757,9 +725,6 @@ class InstanceMemberInferrer {
757725
}
758726
}
759727

760-
/// A class of exception that is not used anywhere else.
761-
class _CycleException implements Exception {}
762-
763728
extension on InterfaceElementImpl {
764729
bool get isBase {
765730
switch (this) {

pkg/analyzer/lib/src/summary2/top_level_inference.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,12 @@ class TopLevelInference {
9898
}
9999

100100
void _performOverrideInference() {
101+
var interfacesToInfer = linker.builders.values.expand((builder) {
102+
return builder.element.children.whereType<InterfaceElementImpl>();
103+
}).toList();
104+
101105
var inferrer = InstanceMemberInferrer(linker.inheritance);
102-
for (var builder in linker.builders.values) {
103-
inferrer.inferLibrary(builder.element);
104-
}
106+
inferrer.perform(interfacesToInfer);
105107
}
106108
}
107109

0 commit comments

Comments
 (0)