@@ -57,62 +57,86 @@ class ClassHierarchyBuilder {
57
57
58
58
ClassHierarchyBuilder (this .objectClass);
59
59
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 ) {
63
74
// Don't check overrides involving duplicated members.
64
- return member ;
75
+ return a ;
65
76
}
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;
71
82
if (mergeKind == MergeKind .interfaces) {
72
83
cls.addProblem (messageInheritedMembersConflict, cls.charOffset,
73
84
cls.fullNameForErrors.length,
74
85
context: < LocatedMessage > [
75
86
messageInheritedMembersConflictCause1.withLocation (
76
- member .fileUri, member .charOffset, name.length),
87
+ a .fileUri, a .charOffset, name.length),
77
88
messageInheritedMembersConflictCause2.withLocation (
78
- superMember .fileUri, superMember .charOffset, name.length),
89
+ b .fileUri, b .charOffset, name.length),
79
90
]);
80
91
} else {
81
92
cls.addProblem (messageDeclaredMemberConflictsWithInheritedMember,
82
- member .charOffset, name.length,
93
+ a .charOffset, name.length,
83
94
context: < LocatedMessage > [
84
95
messageDeclaredMemberConflictsWithInheritedMemberCause
85
- .withLocation (
86
- superMember.fileUri, superMember.charOffset, name.length)
96
+ .withLocation (b.fileUri, b.charOffset, name.length)
87
97
]);
88
98
}
89
99
}
90
- if (target .name == noSuchMethodName && ! target .isAbstract) {
100
+ if (aTarget .name == noSuchMethodName && ! aTarget .isAbstract) {
91
101
hasNoSuchMethod = true ;
92
102
}
93
- Declaration result = member ;
103
+ Declaration result = a ;
94
104
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) {
98
108
// An abstract method doesn't override an implemention inherited from a
99
109
// superclass.
100
- result = superMember ;
110
+ result = b ;
101
111
} else {
102
112
abstractMemberCount++ ;
103
113
}
104
114
}
105
115
return result;
106
116
}
107
117
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) {
109
126
Member target = member.target;
110
127
if (mergeKind == MergeKind .superclass && target.isAbstract) {
111
128
abstractMemberCount++ ;
112
129
}
113
130
}
114
131
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 (
116
140
KernelClassBuilder cls, Declaration member, MergeKind mergeKind) {
117
141
Member target = member.target;
118
142
if (mergeKind == MergeKind .superclass && target.isAbstract) {
@@ -153,42 +177,42 @@ class ClassHierarchyBuilder {
153
177
scope = mixin .scope;
154
178
}
155
179
}
156
- List <Declaration > sortedLocals =
180
+ List <Declaration > localMembers =
157
181
new List <Declaration >.from (scope.local.values)
158
182
..sort (compareDeclarations);
159
- List <Declaration > sortedSetters =
183
+ List <Declaration > localSetters =
160
184
new List <Declaration >.from (scope.setters.values)
161
185
..sort (compareDeclarations);
162
- List <Declaration > allMembers ;
163
- List <Declaration > allSetters ;
186
+ List <Declaration > classMembers ;
187
+ List <Declaration > classSetters ;
164
188
List <Declaration > interfaceMembers;
165
189
List <Declaration > interfaceSetters;
166
190
if (supernode == null ) {
167
191
// This should be Object.
168
- interfaceMembers = allMembers = sortedLocals ;
169
- interfaceSetters = allSetters = sortedSetters ;
192
+ interfaceMembers = classMembers = localMembers ;
193
+ interfaceSetters = classSetters = localSetters ;
170
194
} 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);
175
199
List <KernelTypeBuilder > interfaces = cls.interfaces;
176
200
if (interfaces != null ) {
177
201
MergeResult result = mergeInterfaces (cls, supernode, interfaces);
178
202
interfaceMembers = result.mergedMembers;
179
203
interfaceSetters = result.mergedSetters;
180
204
} else {
181
- interfaceMembers = allMembers ;
182
- interfaceSetters = allSetters ;
205
+ interfaceMembers = classMembers ;
206
+ interfaceSetters = classSetters ;
183
207
}
184
208
}
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 );
188
212
189
213
if (abstractMemberCount != 0 && ! cls.isAbstract) {
190
214
if (! hasNoSuchMethod) {
191
- reportMissingMembers (cls, allMembers, allSetters );
215
+ reportMissingMembers (cls, classMembers, classSetters );
192
216
}
193
217
installNsmHandlers (cls);
194
218
}
@@ -238,14 +262,14 @@ class ClassHierarchyBuilder {
238
262
239
263
/// Merge [and check] accessors. This entails removing setters corresponding
240
264
/// 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 ) {
243
267
List <Declaration > overriddenSetters;
244
268
int i = 0 ;
245
269
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];
249
273
final int compare = compareDeclarations (member, setter);
250
274
if (compare == 0 ) {
251
275
if (member.isField) {
@@ -284,34 +308,34 @@ class ClassHierarchyBuilder {
284
308
// cannot be a conflict.
285
309
286
310
if (overriddenSetters != null ) {
287
- // Remove [overriddenSetters] from [allSetters ] by copying [allSetters ]
311
+ // Remove [overriddenSetters] from [setters ] by copying [setters ]
288
312
// to itself.
289
313
int i = 0 ;
290
314
int j = 0 ;
291
315
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]) {
294
318
i++ ;
295
319
j++ ;
296
320
} else {
297
- allSetters [storeIndex++ ] = allSetters [i++ ];
321
+ setters [storeIndex++ ] = setters [i++ ];
298
322
}
299
323
}
300
- while (i < allSetters .length) {
301
- allSetters [storeIndex++ ] = allSetters [i++ ];
324
+ while (i < setters .length) {
325
+ setters [storeIndex++ ] = setters [i++ ];
302
326
}
303
- allSetters .length = storeIndex;
327
+ setters .length = storeIndex;
304
328
}
305
329
}
306
330
307
- void reportMissingMembers (KernelClassBuilder cls,
308
- List <Declaration > allMembers, List < Declaration > allSetters ) {
331
+ void reportMissingMembers (KernelClassBuilder cls, List < Declaration > members,
332
+ List <Declaration > setters ) {
309
333
List <LocatedMessage > context = < LocatedMessage > [];
310
334
List <String > missingNames = < String > [];
311
335
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];
315
339
Member target = declaration.target;
316
340
if (target.isAbstract && isNameVisibleIn (target.name, cls.library)) {
317
341
String name = declaration.fullNameForErrors;
@@ -357,51 +381,47 @@ class ClassHierarchyBuilder {
357
381
return type is KernelNamedTypeBuilder ? type.declaration : null ;
358
382
}
359
383
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 ,
367
388
growable: true );
368
389
369
- int mergedMemberCount = 0 ;
390
+ int storeIndex = 0 ;
370
391
371
392
int i = 0 ;
372
393
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 );
377
398
if (compare == 0 ) {
378
- mergedMembers[mergedMemberCount++ ] =
379
- handleOverride (cls, localMember, superMember, mergeKind);
399
+ result[storeIndex++ ] = handleMergeConflict (cls, a, b, mergeKind);
380
400
i++ ;
381
401
j++ ;
382
402
} else if (compare < 0 ) {
383
- handleNewMember (localMember , mergeKind);
384
- mergedMembers[mergedMemberCount ++ ] = localMember ;
403
+ handleOnlyA (a , mergeKind);
404
+ result[storeIndex ++ ] = a ;
385
405
i++ ;
386
406
} else {
387
- handleInheritance (cls, superMember , mergeKind);
388
- mergedMembers[mergedMemberCount ++ ] = superMember ;
407
+ handleOnlyB (cls, b , mergeKind);
408
+ result[storeIndex ++ ] = b ;
389
409
j++ ;
390
410
}
391
411
}
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 ;
396
416
i++ ;
397
417
}
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 ;
402
422
j++ ;
403
423
}
404
- return mergedMembers ..length = mergedMemberCount ;
424
+ return result ..length = storeIndex ;
405
425
}
406
426
}
407
427
0 commit comments