@@ -97,14 +97,16 @@ class ClassHierarchyBuilder {
97
97
]);
98
98
}
99
99
}
100
- if (aTarget.name == noSuchMethodName && ! aTarget.isAbstract) {
100
+ if (mergeKind == MergeKind .superclass &&
101
+ aTarget.name == noSuchMethodName &&
102
+ ! aTarget.isAbstract) {
101
103
hasNoSuchMethod = true ;
102
104
}
103
105
Declaration result = a;
104
106
if (mergeKind == MergeKind .interfaces) {
105
107
// TODO(ahe): Combine the signatures of a and b.
106
108
} else if (aTarget.isAbstract) {
107
- if (! bTarget.isAbstract) {
109
+ if (mergeKind == MergeKind .superclass && ! bTarget.isAbstract) {
108
110
// An abstract method doesn't override an implemention inherited from a
109
111
// superclass.
110
112
result = b;
@@ -124,7 +126,8 @@ class ClassHierarchyBuilder {
124
126
/// implementing/overriding anything.
125
127
void handleOnlyA (Declaration member, MergeKind mergeKind) {
126
128
Member target = member.target;
127
- if (mergeKind == MergeKind .superclass && target.isAbstract) {
129
+ if (mergeKind == MergeKind .supertypes ||
130
+ (mergeKind == MergeKind .superclass && target.isAbstract)) {
128
131
abstractMemberCount++ ;
129
132
}
130
133
}
@@ -139,7 +142,8 @@ class ClassHierarchyBuilder {
139
142
void handleOnlyB (
140
143
KernelClassBuilder cls, Declaration member, MergeKind mergeKind) {
141
144
Member target = member.target;
142
- if (mergeKind == MergeKind .superclass && target.isAbstract) {
145
+ if (mergeKind == MergeKind .supertypes ||
146
+ (mergeKind == MergeKind .superclass && target.isAbstract)) {
143
147
if (isNameVisibleIn (target.name, cls.library)) {
144
148
abstractMemberCount++ ;
145
149
}
@@ -189,8 +193,8 @@ class ClassHierarchyBuilder {
189
193
List <Declaration > interfaceSetters;
190
194
if (supernode == null ) {
191
195
// This should be Object.
192
- interfaceMembers = classMembers = localMembers;
193
- interfaceSetters = classSetters = localSetters;
196
+ classMembers = localMembers;
197
+ classSetters = localSetters;
194
198
} else {
195
199
classMembers = merge (
196
200
cls, localMembers, supernode.classMembers, MergeKind .superclass);
@@ -202,8 +206,16 @@ class ClassHierarchyBuilder {
202
206
interfaceMembers = result.mergedMembers;
203
207
interfaceSetters = result.mergedSetters;
204
208
} else {
205
- interfaceMembers = classMembers;
206
- interfaceSetters = classSetters;
209
+ interfaceMembers = supernode.interfaceMembers;
210
+ interfaceSetters = supernode.interfaceSetters;
211
+ }
212
+ if (interfaceMembers != null ) {
213
+ interfaceMembers =
214
+ merge (cls, classMembers, interfaceMembers, MergeKind .supertypes);
215
+ }
216
+ if (interfaceMembers != null ) {
217
+ interfaceSetters =
218
+ merge (cls, classSetters, interfaceSetters, MergeKind .supertypes);
207
219
}
208
220
}
209
221
nodes[cls] = new ClassHierarchyNode (cls, scope, classMembers, classSetters,
@@ -223,19 +235,21 @@ class ClassHierarchyBuilder {
223
235
MergeResult mergeInterfaces (KernelClassBuilder cls,
224
236
ClassHierarchyNode supernode, List <KernelTypeBuilder > interfaces) {
225
237
List <List <Declaration >> memberLists =
226
- List <List <Declaration >>(interfaces.length + 1 );
238
+ new List <List <Declaration >>(interfaces.length + 1 );
227
239
List <List <Declaration >> setterLists =
228
- List <List <Declaration >>(interfaces.length + 1 );
240
+ new List <List <Declaration >>(interfaces.length + 1 );
229
241
memberLists[0 ] = supernode.interfaceMembers;
230
242
setterLists[0 ] = supernode.interfaceSetters;
231
243
for (int i = 0 ; i < interfaces.length; i++ ) {
232
244
ClassHierarchyNode interfaceNode = getNode (interfaces[i]);
233
245
if (interfaceNode == null ) {
234
- memberLists[i + 1 ] = < Declaration > [] ;
235
- setterLists[i + 1 ] = < Declaration > [] ;
246
+ memberLists[i + 1 ] = null ;
247
+ setterLists[i + 1 ] = null ;
236
248
} else {
237
- memberLists[i + 1 ] = interfaceNode.interfaceMembers;
238
- setterLists[i + 1 ] = interfaceNode.interfaceSetters;
249
+ memberLists[i + 1 ] =
250
+ interfaceNode.interfaceMembers ?? interfaceNode.classMembers;
251
+ setterLists[i + 1 ] =
252
+ interfaceNode.interfaceSetters ?? interfaceNode.classSetters;
239
253
}
240
254
}
241
255
return new MergeResult (
@@ -250,7 +264,15 @@ class ClassHierarchyBuilder {
250
264
while (input.length > 1 ) {
251
265
List <List <Declaration >> output = < List <Declaration >> [];
252
266
for (int i = 0 ; i < input.length - 1 ; i += 2 ) {
253
- output.add (merge (cls, input[i], input[i + 1 ], MergeKind .interfaces));
267
+ List <Declaration > first = input[i];
268
+ List <Declaration > second = input[i + 1 ];
269
+ if (first == null ) {
270
+ output.add (second);
271
+ } else if (second == null ) {
272
+ output.add (first);
273
+ } else {
274
+ output.add (merge (cls, first, second, MergeKind .interfaces));
275
+ }
254
276
}
255
277
if (input.length.isOdd) {
256
278
output.add (input.last);
@@ -350,6 +372,7 @@ class ClassHierarchyBuilder {
350
372
}
351
373
}
352
374
}
375
+ if (missingNames.isEmpty) return ;
353
376
cls.addProblem (
354
377
templateMissingImplementationNotAbstract.withArguments (
355
378
cls.fullNameForErrors, missingNames),
0 commit comments