Skip to content

Commit baa7da3

Browse files
scheglovCommit Queue
authored andcommitted
Elements. Fix method top-merge reuse and default constructor flag
Correct two issues in element handling: * In `InheritanceManager3._topMerge`, when merging methods, check for an existing `MethodElementImpl` at `@method/<name>` (not a setter). If present, reuse it; otherwise assert the slot is empty before synthesizing. Similar assertions are added to getter/setter paths to guard against accidental reuse of a wrong-kind element. * In `SubstitutedConstructorElementImpl`, fix `isDefaultConstructor` to forward to `baseElement.isDefaultConstructor` (it previously forwarded to `isConst`). These changes prevent creating fresh synthetic methods when a correct method already exists, preserving element identity and avoiding wrong-kind lookups. The constructor fix restores accurate default constructor detection, which can affect downstream diagnostics and presentation. Additional tests cover method top-merge in both “existing” and “synthetic” scenarios, aligning method coverage with existing getter/setter cases. Change-Id: I09c3aaa7cb89f216d6d3101bbad835567df5b213 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447961 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 51b7329 commit baa7da3

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,9 +1069,10 @@ class InheritanceManager3 {
10691069
var elementReference = targetClass.reference!
10701070
.getChild('@method')
10711071
.getChild(fragmentName);
1072-
if (elementReference.element case SetterElementImpl result) {
1072+
if (elementReference.element case MethodElementImpl result) {
10731073
return result;
10741074
}
1075+
assert(elementReference.element == null);
10751076

10761077
var resultFragment = MethodFragmentImpl(name: fragmentName);
10771078
resultFragment.enclosingFragment = targetClass.firstFragment;
@@ -1106,6 +1107,7 @@ class InheritanceManager3 {
11061107
if (elementReference.element case GetterElementImpl result) {
11071108
return result;
11081109
}
1110+
assert(elementReference.element == null);
11091111

11101112
var fragment = GetterFragmentImpl(name: fragmentName);
11111113
resultFragment = fragment;
@@ -1120,6 +1122,7 @@ class InheritanceManager3 {
11201122
if (elementReference.element case SetterElementImpl result) {
11211123
return result;
11221124
}
1125+
assert(elementReference.element == null);
11231126

11241127
var fragment = SetterFragmentImpl(name: fragmentName);
11251128
resultFragment = fragment;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class SubstitutedConstructorElementImpl extends SubstitutedExecutableElementImpl
6161
bool get isConst => baseElement.isConst;
6262

6363
@override
64-
bool get isDefaultConstructor => baseElement.isConst;
64+
bool get isDefaultConstructor => baseElement.isDefaultConstructor;
6565

6666
@override
6767
bool get isFactory => baseElement.isFactory;

pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,27 @@ abstract class X extends A implements B {}
12161216
);
12171217
}
12181218

1219-
test_getMember_optIn_topMerge_method() async {
1219+
test_getMember_optIn_topMerge_method_existing() async {
1220+
await resolveTestCode('''
1221+
class A {
1222+
dynamic foo() {}
1223+
}
1224+
1225+
class B {
1226+
Object? foo() {}
1227+
}
1228+
1229+
class X extends A implements B {}
1230+
''');
1231+
1232+
_assertGetMember(
1233+
className: 'X',
1234+
name: 'foo',
1235+
expected: 'B.foo: Object? Function()',
1236+
);
1237+
}
1238+
1239+
test_getMember_optIn_topMerge_method_synthetic() async {
12201240
await resolveTestCode('''
12211241
class A {
12221242
Object? foo(dynamic x) {}

0 commit comments

Comments
 (0)