Skip to content

Commit 36b38d5

Browse files
committed
Fine. Support for duplicate class members.
Change-Id: Id574d8a8a2a77b675d0b744e37fac137827ab36b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423080 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Paul Berry <[email protected]>
1 parent c5305e2 commit 36b38d5

File tree

4 files changed

+1076
-89
lines changed

4 files changed

+1076
-89
lines changed

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

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ class LibraryManifestBuilder {
260260
return;
261261
}
262262

263+
if (instanceItem.replaceDuplicate(lookupName)) {
264+
return;
265+
}
266+
263267
var item = _getOrBuildElementItem(element, () {
264268
return InstanceItemGetterItem.fromElement(
265269
id: ManifestItemId.generate(),
@@ -270,33 +274,6 @@ class LibraryManifestBuilder {
270274
instanceItem.declaredMembers[lookupName] = item;
271275
}
272276

273-
void _addInstanceElementInstanceExecutable({
274-
required EncodeContext encodingContext,
275-
required InstanceItem instanceItem,
276-
required ExecutableElementImpl2 element,
277-
}) {
278-
switch (element) {
279-
case GetterElementImpl():
280-
_addInstanceElementGetter(
281-
encodingContext: encodingContext,
282-
instanceItem: instanceItem,
283-
element: element,
284-
);
285-
case MethodElementImpl2():
286-
_addInstanceElementMethod(
287-
encodingContext: encodingContext,
288-
instanceItem: instanceItem,
289-
element: element,
290-
);
291-
case SetterElementImpl():
292-
_addInstanceElementSetter(
293-
encodingContext: encodingContext,
294-
instanceItem: instanceItem,
295-
element: element,
296-
);
297-
}
298-
}
299-
300277
void _addInstanceElementMethod({
301278
required EncodeContext encodingContext,
302279
required InstanceItem instanceItem,
@@ -307,6 +284,10 @@ class LibraryManifestBuilder {
307284
return;
308285
}
309286

287+
if (instanceItem.replaceDuplicate(lookupName)) {
288+
return;
289+
}
290+
310291
var item = _getOrBuildElementItem(element, () {
311292
return InstanceItemMethodItem.fromElement(
312293
id: ManifestItemId.generate(),
@@ -327,6 +308,10 @@ class LibraryManifestBuilder {
327308
return;
328309
}
329310

311+
if (instanceItem.replaceDuplicate(lookupName)) {
312+
return;
313+
}
314+
330315
var item = _getOrBuildElementItem(element, () {
331316
return InstanceItemSetterItem.fromElement(
332317
id: ManifestItemId.generate(),
@@ -398,17 +383,32 @@ class LibraryManifestBuilder {
398383
required InterfaceElementImpl2 interfaceElement,
399384
required InterfaceItem interfaceItem,
400385
}) {
401-
var inheritance = interfaceElement.inheritanceManager;
402-
var map = inheritance.getInterface2(interfaceElement).map2;
403-
for (var entry in map.entries) {
404-
var executable = entry.value;
405-
if (executable.enclosingElement2 == interfaceElement) {
406-
// SAFETY: declared in the element are always impl.
407-
executable as ExecutableElementImpl2;
408-
_addInstanceElementInstanceExecutable(
386+
for (var getter in interfaceElement.getters2) {
387+
if (!getter.isStatic) {
388+
_addInstanceElementGetter(
389+
encodingContext: encodingContext,
390+
instanceItem: interfaceItem,
391+
element: getter,
392+
);
393+
}
394+
}
395+
396+
for (var method in interfaceElement.methods2) {
397+
if (!method.isStatic) {
398+
_addInstanceElementMethod(
399+
encodingContext: encodingContext,
400+
instanceItem: interfaceItem,
401+
element: method,
402+
);
403+
}
404+
}
405+
406+
for (var setter in interfaceElement.setters2) {
407+
if (!setter.isStatic) {
408+
_addInstanceElementSetter(
409409
encodingContext: encodingContext,
410410
instanceItem: interfaceItem,
411-
element: executable,
411+
element: setter,
412412
);
413413
}
414414
}

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ sealed class InstanceItem<E extends InstanceElementImpl2>
8585
return declaredMembers[name]?.id;
8686
}
8787

88+
/// If there is already a declared member with [name], replace it with a
89+
/// fresh instance of [InstanceItemDuplicateItem] and return `true`.
90+
/// Otherwise return `false`.
91+
bool replaceDuplicate(LookupName name) {
92+
if (declaredMembers.containsKey(name)) {
93+
declaredMembers[name] = InstanceItemDuplicateItem();
94+
return true;
95+
}
96+
return false;
97+
}
98+
8899
@override
89100
void write(BufferedSink sink) {
90101
super.write(sink);
@@ -106,6 +117,54 @@ sealed class InstanceItem<E extends InstanceElementImpl2>
106117
}
107118
}
108119

120+
/// Placeholder for a name that has duplicate declared member.
121+
/// It is always given a new ID.
122+
class InstanceItemDuplicateItem
123+
extends InstanceItemMemberItem<ExecutableElementImpl2> {
124+
factory InstanceItemDuplicateItem() {
125+
return InstanceItemDuplicateItem._(
126+
id: ManifestItemId.generate(),
127+
metadata: ManifestMetadata(annotations: []),
128+
isStatic: false,
129+
);
130+
}
131+
132+
factory InstanceItemDuplicateItem.read(SummaryDataReader reader) {
133+
return InstanceItemDuplicateItem._(
134+
id: ManifestItemId.read(reader),
135+
metadata: ManifestMetadata.read(reader),
136+
isStatic: reader.readBool(),
137+
);
138+
}
139+
140+
InstanceItemDuplicateItem._({
141+
required super.id,
142+
required super.metadata,
143+
required super.isStatic,
144+
});
145+
146+
@override
147+
bool match(MatchContext context, ExecutableElementImpl2 element) {
148+
super.match(context, element); // we ignore it
149+
// Duplicate items don't have any specific information, they are just
150+
// a flag, that previously the same name was declared twice. So, there is
151+
// no way to meaningfully match them. We always return `false`, and
152+
// build a new item (and ID) for this name.
153+
//
154+
// The reason is that we don't want to prefer first or last duplicated
155+
// element, we just wait until there is no error. And once it is fixed,
156+
// we will build the actual item, with a new ID, and recompute all uses
157+
// once again.
158+
return false;
159+
}
160+
161+
@override
162+
void write(BufferedSink sink) {
163+
sink.writeEnum(_ManifestItemKind2.instanceDuplicate);
164+
super.write(sink);
165+
}
166+
}
167+
109168
class InstanceItemGetterItem extends InstanceItemMemberItem<GetterElementImpl> {
110169
final ManifestType returnType;
111170
final ManifestNode? constInitializer;
@@ -186,6 +245,8 @@ sealed class InstanceItemMemberItem<E extends ExecutableElementImpl2>
186245
SummaryDataReader reader) {
187246
var kind = reader.readEnum(_ManifestItemKind2.values);
188247
switch (kind) {
248+
case _ManifestItemKind2.instanceDuplicate:
249+
return InstanceItemDuplicateItem.read(reader);
189250
case _ManifestItemKind2.instanceGetter:
190251
return InstanceItemGetterItem.read(reader);
191252
case _ManifestItemKind2.instanceMethod:
@@ -770,6 +831,7 @@ enum _ManifestItemKind {
770831
}
771832

772833
enum _ManifestItemKind2 {
834+
instanceDuplicate,
773835
instanceGetter,
774836
instanceMethod,
775837
instanceSetter,

0 commit comments

Comments
 (0)