Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 1dc920e

Browse files
Change names to reflect merge isn't used only for superclasses
Change-Id: I06a6fb3272e394ba2c7915f457c4c3ebf7d21d07 Reviewed-on: https://dart-review.googlesource.com/c/87966 Reviewed-by: Dmitry Stefantsov <[email protected]>
1 parent 50ea634 commit 1dc920e

File tree

1 file changed

+102
-82
lines changed

1 file changed

+102
-82
lines changed

pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart

Lines changed: 102 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -57,62 +57,86 @@ class ClassHierarchyBuilder {
5757

5858
ClassHierarchyBuilder(this.objectClass);
5959

60-
Declaration handleOverride(KernelClassBuilder cls, Declaration member,
61-
Declaration superMember, MergeKind mergeKind) {
62-
if (member.next != null || superMember.next != null) {
60+
/// A merge conflict arises when merging two lists that each have an element
61+
/// with the same name.
62+
///
63+
/// If [mergeKind] is `MergeKind.superclass`, [a] should override [b].
64+
///
65+
/// If [mergeKind] is `MergeKind.interfaces`, we need to record them and
66+
/// solve the conflict later.
67+
///
68+
/// If [mergeKind] is `MergeKind.supertypes`, [a] should implement [b], and
69+
/// [b] is implicitly abstract.
70+
Declaration handleMergeConflict(KernelClassBuilder cls, Declaration a,
71+
Declaration b, MergeKind mergeKind) {
72+
if (a == b) return a;
73+
if (a.next != null || b.next != null) {
6374
// Don't check overrides involving duplicated members.
64-
return member;
75+
return a;
6576
}
66-
Member target = member.target;
67-
Member superTarget = superMember.target;
68-
if ((memberKind(target) ?? ProcedureKind.Getter) !=
69-
(memberKind(superTarget) ?? ProcedureKind.Getter)) {
70-
String name = member.fullNameForErrors;
77+
Member aTarget = a.target;
78+
Member bTarget = b.target;
79+
if ((memberKind(aTarget) ?? ProcedureKind.Getter) !=
80+
(memberKind(bTarget) ?? ProcedureKind.Getter)) {
81+
String name = a.fullNameForErrors;
7182
if (mergeKind == MergeKind.interfaces) {
7283
cls.addProblem(messageInheritedMembersConflict, cls.charOffset,
7384
cls.fullNameForErrors.length,
7485
context: <LocatedMessage>[
7586
messageInheritedMembersConflictCause1.withLocation(
76-
member.fileUri, member.charOffset, name.length),
87+
a.fileUri, a.charOffset, name.length),
7788
messageInheritedMembersConflictCause2.withLocation(
78-
superMember.fileUri, superMember.charOffset, name.length),
89+
b.fileUri, b.charOffset, name.length),
7990
]);
8091
} else {
8192
cls.addProblem(messageDeclaredMemberConflictsWithInheritedMember,
82-
member.charOffset, name.length,
93+
a.charOffset, name.length,
8394
context: <LocatedMessage>[
8495
messageDeclaredMemberConflictsWithInheritedMemberCause
85-
.withLocation(
86-
superMember.fileUri, superMember.charOffset, name.length)
96+
.withLocation(b.fileUri, b.charOffset, name.length)
8797
]);
8898
}
8999
}
90-
if (target.name == noSuchMethodName && !target.isAbstract) {
100+
if (aTarget.name == noSuchMethodName && !aTarget.isAbstract) {
91101
hasNoSuchMethod = true;
92102
}
93-
Declaration result = member;
103+
Declaration result = a;
94104
if (mergeKind == MergeKind.interfaces) {
95-
// TODO(ahe): Combine the signatures of member and superMember.
96-
} else if (target.isAbstract) {
97-
if (!superTarget.isAbstract) {
105+
// TODO(ahe): Combine the signatures of a and b.
106+
} else if (aTarget.isAbstract) {
107+
if (!bTarget.isAbstract) {
98108
// An abstract method doesn't override an implemention inherited from a
99109
// superclass.
100-
result = superMember;
110+
result = b;
101111
} else {
102112
abstractMemberCount++;
103113
}
104114
}
105115
return result;
106116
}
107117

108-
void handleNewMember(Declaration member, MergeKind mergeKind) {
118+
/// If [mergeKind] is `MergeKind.superclass` [member] is declared in current
119+
/// class, and isn't overriding a method from the superclass.
120+
///
121+
/// If [mergeKind] is `MergeKind.interfaces`, [member] is ignored for now.
122+
///
123+
/// If [mergeKind] is `MergeKind.supertypes`, [member] isn't
124+
/// implementing/overriding anything.
125+
void handleOnlyA(Declaration member, MergeKind mergeKind) {
109126
Member target = member.target;
110127
if (mergeKind == MergeKind.superclass && target.isAbstract) {
111128
abstractMemberCount++;
112129
}
113130
}
114131

115-
void handleInheritance(
132+
/// If [mergeKind] is `MergeKind.superclass` [member] is being inherited from
133+
/// a superclass.
134+
///
135+
/// If [mergeKind] is `MergeKind.interfaces`, [member] is ignored for now.
136+
///
137+
/// If [mergeKind] is `MergeKind.supertypes`, [member] is implicitly
138+
/// abstract, and not implemented.
139+
void handleOnlyB(
116140
KernelClassBuilder cls, Declaration member, MergeKind mergeKind) {
117141
Member target = member.target;
118142
if (mergeKind == MergeKind.superclass && target.isAbstract) {
@@ -153,42 +177,42 @@ class ClassHierarchyBuilder {
153177
scope = mixin.scope;
154178
}
155179
}
156-
List<Declaration> sortedLocals =
180+
List<Declaration> localMembers =
157181
new List<Declaration>.from(scope.local.values)
158182
..sort(compareDeclarations);
159-
List<Declaration> sortedSetters =
183+
List<Declaration> localSetters =
160184
new List<Declaration>.from(scope.setters.values)
161185
..sort(compareDeclarations);
162-
List<Declaration> allMembers;
163-
List<Declaration> allSetters;
186+
List<Declaration> classMembers;
187+
List<Declaration> classSetters;
164188
List<Declaration> interfaceMembers;
165189
List<Declaration> interfaceSetters;
166190
if (supernode == null) {
167191
// This should be Object.
168-
interfaceMembers = allMembers = sortedLocals;
169-
interfaceSetters = allSetters = sortedSetters;
192+
interfaceMembers = classMembers = localMembers;
193+
interfaceSetters = classSetters = localSetters;
170194
} else {
171-
allMembers = merge(
172-
cls, sortedLocals, supernode.classMembers, MergeKind.superclass);
173-
allSetters = merge(
174-
cls, sortedSetters, supernode.classSetters, MergeKind.superclass);
195+
classMembers = merge(
196+
cls, localMembers, supernode.classMembers, MergeKind.superclass);
197+
classSetters = merge(
198+
cls, localSetters, supernode.classSetters, MergeKind.superclass);
175199
List<KernelTypeBuilder> interfaces = cls.interfaces;
176200
if (interfaces != null) {
177201
MergeResult result = mergeInterfaces(cls, supernode, interfaces);
178202
interfaceMembers = result.mergedMembers;
179203
interfaceSetters = result.mergedSetters;
180204
} else {
181-
interfaceMembers = allMembers;
182-
interfaceSetters = allSetters;
205+
interfaceMembers = classMembers;
206+
interfaceSetters = classSetters;
183207
}
184208
}
185-
nodes[cls] = new ClassHierarchyNode(
186-
cls, scope, allMembers, allSetters, interfaceMembers, interfaceSetters);
187-
mergeAccessors(cls, allMembers, allSetters);
209+
nodes[cls] = new ClassHierarchyNode(cls, scope, classMembers, classSetters,
210+
interfaceMembers, interfaceSetters);
211+
mergeAccessors(cls, classMembers, classSetters);
188212

189213
if (abstractMemberCount != 0 && !cls.isAbstract) {
190214
if (!hasNoSuchMethod) {
191-
reportMissingMembers(cls, allMembers, allSetters);
215+
reportMissingMembers(cls, classMembers, classSetters);
192216
}
193217
installNsmHandlers(cls);
194218
}
@@ -238,14 +262,14 @@ class ClassHierarchyBuilder {
238262

239263
/// Merge [and check] accessors. This entails removing setters corresponding
240264
/// to fields, and checking that setters don't override regular methods.
241-
void mergeAccessors(KernelClassBuilder cls, List<Declaration> allMembers,
242-
List<Declaration> allSetters) {
265+
void mergeAccessors(KernelClassBuilder cls, List<Declaration> members,
266+
List<Declaration> setters) {
243267
List<Declaration> overriddenSetters;
244268
int i = 0;
245269
int j = 0;
246-
while (i < allMembers.length && j < allSetters.length) {
247-
Declaration member = allMembers[i];
248-
Declaration setter = allSetters[j];
270+
while (i < members.length && j < setters.length) {
271+
Declaration member = members[i];
272+
Declaration setter = setters[j];
249273
final int compare = compareDeclarations(member, setter);
250274
if (compare == 0) {
251275
if (member.isField) {
@@ -284,34 +308,34 @@ class ClassHierarchyBuilder {
284308
// cannot be a conflict.
285309

286310
if (overriddenSetters != null) {
287-
// Remove [overriddenSetters] from [allSetters] by copying [allSetters]
311+
// Remove [overriddenSetters] from [setters] by copying [setters]
288312
// to itself.
289313
int i = 0;
290314
int j = 0;
291315
int storeIndex = 0;
292-
while (i < allSetters.length && j < overriddenSetters.length) {
293-
if (allSetters[i] == overriddenSetters[j]) {
316+
while (i < setters.length && j < overriddenSetters.length) {
317+
if (setters[i] == overriddenSetters[j]) {
294318
i++;
295319
j++;
296320
} else {
297-
allSetters[storeIndex++] = allSetters[i++];
321+
setters[storeIndex++] = setters[i++];
298322
}
299323
}
300-
while (i < allSetters.length) {
301-
allSetters[storeIndex++] = allSetters[i++];
324+
while (i < setters.length) {
325+
setters[storeIndex++] = setters[i++];
302326
}
303-
allSetters.length = storeIndex;
327+
setters.length = storeIndex;
304328
}
305329
}
306330

307-
void reportMissingMembers(KernelClassBuilder cls,
308-
List<Declaration> allMembers, List<Declaration> allSetters) {
331+
void reportMissingMembers(KernelClassBuilder cls, List<Declaration> members,
332+
List<Declaration> setters) {
309333
List<LocatedMessage> context = <LocatedMessage>[];
310334
List<String> missingNames = <String>[];
311335
for (int j = 0; j < 2; j++) {
312-
List<Declaration> members = j == 0 ? allMembers : allSetters;
313-
for (int i = 0; i < members.length; i++) {
314-
Declaration declaration = members[i];
336+
List<Declaration> declarations = j == 0 ? members : setters;
337+
for (int i = 0; i < declarations.length; i++) {
338+
Declaration declaration = declarations[i];
315339
Member target = declaration.target;
316340
if (target.isAbstract && isNameVisibleIn(target.name, cls.library)) {
317341
String name = declaration.fullNameForErrors;
@@ -357,51 +381,47 @@ class ClassHierarchyBuilder {
357381
return type is KernelNamedTypeBuilder ? type.declaration : null;
358382
}
359383

360-
List<Declaration> merge(
361-
KernelClassBuilder cls,
362-
List<Declaration> localMembers,
363-
List<Declaration> superMembers,
364-
MergeKind mergeKind) {
365-
final List<Declaration> mergedMembers = new List<Declaration>.filled(
366-
localMembers.length + superMembers.length, null,
384+
List<Declaration> merge(KernelClassBuilder cls, List<Declaration> aList,
385+
List<Declaration> bList, MergeKind mergeKind) {
386+
final List<Declaration> result = new List<Declaration>.filled(
387+
aList.length + bList.length, null,
367388
growable: true);
368389

369-
int mergedMemberCount = 0;
390+
int storeIndex = 0;
370391

371392
int i = 0;
372393
int j = 0;
373-
while (i < localMembers.length && j < superMembers.length) {
374-
final Declaration localMember = localMembers[i];
375-
final Declaration superMember = superMembers[j];
376-
final int compare = compareDeclarations(localMember, superMember);
394+
while (i < aList.length && j < bList.length) {
395+
final Declaration a = aList[i];
396+
final Declaration b = bList[j];
397+
final int compare = compareDeclarations(a, b);
377398
if (compare == 0) {
378-
mergedMembers[mergedMemberCount++] =
379-
handleOverride(cls, localMember, superMember, mergeKind);
399+
result[storeIndex++] = handleMergeConflict(cls, a, b, mergeKind);
380400
i++;
381401
j++;
382402
} else if (compare < 0) {
383-
handleNewMember(localMember, mergeKind);
384-
mergedMembers[mergedMemberCount++] = localMember;
403+
handleOnlyA(a, mergeKind);
404+
result[storeIndex++] = a;
385405
i++;
386406
} else {
387-
handleInheritance(cls, superMember, mergeKind);
388-
mergedMembers[mergedMemberCount++] = superMember;
407+
handleOnlyB(cls, b, mergeKind);
408+
result[storeIndex++] = b;
389409
j++;
390410
}
391411
}
392-
while (i < localMembers.length) {
393-
final Declaration localMember = localMembers[i];
394-
handleNewMember(localMember, mergeKind);
395-
mergedMembers[mergedMemberCount++] = localMember;
412+
while (i < aList.length) {
413+
final Declaration a = aList[i];
414+
handleOnlyA(a, mergeKind);
415+
result[storeIndex++] = a;
396416
i++;
397417
}
398-
while (j < superMembers.length) {
399-
final Declaration superMember = superMembers[j];
400-
handleInheritance(cls, superMember, mergeKind);
401-
mergedMembers[mergedMemberCount++] = superMember;
418+
while (j < bList.length) {
419+
final Declaration b = bList[j];
420+
handleOnlyB(cls, b, mergeKind);
421+
result[storeIndex++] = b;
402422
j++;
403423
}
404-
return mergedMembers..length = mergedMemberCount;
424+
return result..length = storeIndex;
405425
}
406426
}
407427

0 commit comments

Comments
 (0)