Skip to content

Commit 3915216

Browse files
scheglovCommit Queue
authored andcommitted
Fine. Consider class type alias constructors inherited.
Change-Id: I88b95f4a95ec30dca41d04a008a727bf114a3bfd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422366 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent de32acf commit 3915216

File tree

2 files changed

+314
-17
lines changed

2 files changed

+314
-17
lines changed

pkg/analyzer/lib/src/fine/library_manifest.dart

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,64 @@ class LibraryManifestBuilder {
154154
);
155155
}
156156

157+
/// Class type aliases like `class B = A with M;` cannot explicitly declare
158+
/// any members. They have constructors, but these are based on the
159+
/// constructors of the supertype, and change if the supertype constructors
160+
/// change. So, it is enough to record that supertype constructors into
161+
/// the manifest.
162+
void _addClassTypeAliasConstructors() {
163+
var hasConstructors = <ClassElementImpl2>{};
164+
var inheritedMap = <ConstructorElementImpl2, ManifestItemId>{};
165+
166+
void addForElement(ClassElementImpl2 element) {
167+
if (!element.isMixinApplication) {
168+
return;
169+
}
170+
171+
// We might have already processed this element due to recursion.
172+
if (!hasConstructors.add(element)) {
173+
return;
174+
}
175+
176+
// SAFETY: all items are already created.
177+
var item = declaredItems[element] as ClassItem;
178+
179+
// SAFETY: we set `Object` during linking if it is not a class.
180+
var superElement = element.supertype!.element3;
181+
superElement as ClassElementImpl2;
182+
183+
// The supertype could be a mixin application itself.
184+
addForElement(superElement);
185+
186+
for (var constructor in element.constructors2) {
187+
var lookupName = constructor.lookupName?.asLookupName;
188+
if (lookupName == null) {
189+
continue;
190+
}
191+
192+
// SAFETY: we build inherited constructors from existing super.
193+
var superConstructor = constructor.superConstructor2!.baseElement;
194+
195+
// Maybe the super constructor is "inherited" itself.
196+
var id = inheritedMap[superConstructor];
197+
198+
// If not inherited, then must be declared.
199+
id ??= _getInterfaceElementMemberId(superConstructor);
200+
201+
item.inheritedMembers[lookupName] = id;
202+
inheritedMap[constructor] = id;
203+
}
204+
}
205+
206+
for (var libraryElement in libraryElements) {
207+
for (var element in libraryElement.children2) {
208+
if (element is ClassElementImpl2) {
209+
addForElement(element);
210+
}
211+
}
212+
}
213+
}
214+
157215
void _addInheritedInterfaceElementExecutables(InterfaceElementImpl2 element) {
158216
// We don't create items for elements without name.
159217
if (element.lookupName == null) {
@@ -361,6 +419,13 @@ class LibraryManifestBuilder {
361419
required InterfaceElementImpl2 instanceElement,
362420
required InterfaceItem interfaceItem,
363421
}) {
422+
// Class type aliases don't have declared members.
423+
// We don't consider constructors as declared.
424+
if (instanceElement is ClassElementImpl2 &&
425+
instanceElement.isMixinApplication) {
426+
return;
427+
}
428+
364429
for (var constructor in instanceElement.constructors2) {
365430
_addInterfaceElementConstructor(
366431
encodingContext: encodingContext,
@@ -596,6 +661,7 @@ class LibraryManifestBuilder {
596661
}
597662

598663
_addInheritedInterfaceElementsExecutables();
664+
_addClassTypeAliasConstructors();
599665

600666
return newManifests;
601667
}

0 commit comments

Comments
 (0)