Skip to content

Commit 2485242

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Change method override inference to use combined member signature.
dart-lang/language#975 Change-Id: I5cec14a384b124a29dcd5adac0f0be6e5214cc9e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151044 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 43131b5 commit 2485242

File tree

7 files changed

+1255
-460
lines changed

7 files changed

+1255
-460
lines changed

pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_out.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ class C1 extends A implements B {
6666
/*cfe|cfe:builder.member: C2._simpleInstanceOfTrue:bool* Function(dynamic)**/
6767
/*cfe|cfe:builder.member: C2.==:bool* Function(dynamic)**/
6868
class C2 extends B implements A {
69-
/*member: C2.method:dynamic Function(dynamic, {dynamic named})**/
69+
/*cfe|cfe:builder.member: C2.method:dynamic Function(dynamic, {dynamic named})**/
70+
/*analyzer.member: C2.method:Object* Function(Object*, {Object* named})**/
7071
method(o, {named}) {}
7172
}
7273

@@ -98,7 +99,8 @@ class C3 implements A, B {
9899
/*cfe|cfe:builder.member: C4._simpleInstanceOfTrue:bool* Function(dynamic)**/
99100
/*cfe|cfe:builder.member: C4.==:bool* Function(dynamic)**/
100101
class C4 implements B, A {
101-
/*member: C4.method:dynamic Function(dynamic, {dynamic named})**/
102+
/*cfe|cfe:builder.member: C4.method:dynamic Function(dynamic, {dynamic named})**/
103+
/*analyzer.member: C4.method:Object* Function(Object*, {Object* named})**/
102104
method(o, {named}) {}
103105
}
104106

pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart

Lines changed: 70 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,66 @@ class InheritanceManager3 {
5454
/// self-referencing cycles.
5555
final Set<ClassElement> _processingClasses = <ClassElement>{};
5656

57+
/// Combine [candidates] into a single signature in the [targetClass].
58+
///
59+
/// If such signature does not exist, return `null`, and if [conflicts] is
60+
/// not `null`, add a new [Conflict] to it.
61+
ExecutableElement combineSignatures({
62+
@required ClassElement targetClass,
63+
@required List<ExecutableElement> candidates,
64+
@required bool doTopMerge,
65+
@required Name name,
66+
List<Conflict> conflicts,
67+
}) {
68+
// If just one candidate, it is always valid.
69+
if (candidates.length == 1) {
70+
return candidates[0];
71+
}
72+
73+
// Check for a getter/method conflict.
74+
var conflict = _checkForGetterMethodConflict(name, candidates);
75+
if (conflict != null) {
76+
conflicts?.add(conflict);
77+
return null;
78+
}
79+
80+
var validOverrides = <ExecutableElement>[];
81+
for (var i = 0; i < candidates.length; i++) {
82+
var validOverride = candidates[i];
83+
var overrideHelper = CorrectOverrideHelper(
84+
library: targetClass.library,
85+
thisMember: validOverride,
86+
);
87+
for (var j = 0; j < candidates.length; j++) {
88+
var candidate = candidates[j];
89+
if (!overrideHelper.isCorrectOverrideOf(superMember: candidate)) {
90+
validOverride = null;
91+
break;
92+
}
93+
}
94+
if (validOverride != null) {
95+
validOverrides.add(validOverride);
96+
}
97+
}
98+
99+
if (validOverrides.isEmpty) {
100+
conflicts?.add(
101+
CandidatesConflict(
102+
name: name,
103+
candidates: candidates,
104+
),
105+
);
106+
return null;
107+
}
108+
109+
if (doTopMerge) {
110+
var typeSystem = targetClass.library.typeSystem;
111+
return _topMerge(typeSystem, targetClass, validOverrides);
112+
} else {
113+
return validOverrides.first;
114+
}
115+
}
116+
57117
/// Return the result of [getInherited2] with [type] substitution.
58118
ExecutableElement getInherited(InterfaceType type, Name name) {
59119
var rawElement = getInherited2(type.element, name);
@@ -369,9 +429,7 @@ class InheritanceManager3 {
369429
Map<Name, List<ExecutableElement>> namedCandidates, {
370430
@required bool doTopMerge,
371431
}) {
372-
TypeSystemImpl typeSystem = targetClass.library.typeSystem;
373-
374-
List<Conflict> conflicts;
432+
var conflicts = <Conflict>[];
375433

376434
for (var name in namedCandidates.keys) {
377435
if (map.containsKey(name)) {
@@ -380,54 +438,18 @@ class InheritanceManager3 {
380438

381439
var candidates = namedCandidates[name];
382440

383-
// If just one candidate, it is always valid.
384-
if (candidates.length == 1) {
385-
map[name] = candidates[0];
386-
continue;
387-
}
388-
389-
// Check for a getter/method conflict.
390-
var conflict = _checkForGetterMethodConflict(name, candidates);
391-
if (conflict != null) {
392-
conflicts ??= <Conflict>[];
393-
conflicts.add(conflict);
394-
}
395-
396-
var validOverrides = <ExecutableElement>[];
397-
for (var i = 0; i < candidates.length; i++) {
398-
var validOverride = candidates[i];
399-
var overrideHelper = CorrectOverrideHelper(
400-
library: targetClass.library,
401-
thisMember: validOverride,
402-
);
403-
for (var j = 0; j < candidates.length; j++) {
404-
var candidate = candidates[j];
405-
if (!overrideHelper.isCorrectOverrideOf(superMember: candidate)) {
406-
validOverride = null;
407-
break;
408-
}
409-
}
410-
if (validOverride != null) {
411-
validOverrides.add(validOverride);
412-
}
413-
}
441+
var combinedSignature = combineSignatures(
442+
targetClass: targetClass,
443+
candidates: candidates,
444+
doTopMerge: doTopMerge,
445+
name: name,
446+
conflicts: conflicts,
447+
);
414448

415-
if (validOverrides.isEmpty) {
416-
conflicts ??= <Conflict>[];
417-
conflicts.add(
418-
CandidatesConflict(
419-
name: name,
420-
candidates: candidates,
421-
),
422-
);
449+
if (combinedSignature != null) {
450+
map[name] = combinedSignature;
423451
continue;
424452
}
425-
426-
if (doTopMerge) {
427-
map[name] = _topMerge(typeSystem, targetClass, validOverrides);
428-
} else {
429-
map[name] = validOverrides.first;
430-
}
431453
}
432454

433455
return conflicts;

0 commit comments

Comments
 (0)