Augment. Skip field augmentations when checking for duplicate members.

Treat field fragments marked as augmentations like other augmented
members when collecting local member names. Do not add their getter and
setter fragments to the instance or static duplicate scopes, because
they augment existing declarations rather than introduce new local
members.

This avoids secondary duplicateDefinition and conflicting member
diagnostics when a field augmentation targets an existing declaration.
Non-augmenting declarations in augmentation blocks are still checked as
new declarations, so real duplicates continue to be reported.

We don't have yet checks for completed getter / setter from fields and
variables, so tests miss several errors.

Change-Id: I6901aea1770891917c966c11b59cb647aaf4ed86
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/503840
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
Konstantin Shcheglov
2026-05-16 07:53:18 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent d12a4095a4
commit 6c76594af1
4 changed files with 405 additions and 238 deletions
@@ -129,6 +129,9 @@ class MemberDuplicateDefinitionVerifier {
for (var field in member.fields.variables) {
var fieldFragment = field.declaredFragment!;
fieldFragment as FieldFragmentImpl;
if (fieldFragment.isAugmentation) {
continue;
}
var fieldElement = fieldFragment.element;
_checkDuplicateIdentifier(
member.isStatic ? staticScope : instanceScope,
@@ -155,14 +155,11 @@ class A {
void foo() {}
// ^^^
// [context 1] The declaration being augmented.
// [context 2] The first definition of this name.
}
augment class A {
augment int foo = 0;
//^^^^^^^
// [diag.augmentationOfDifferentDeclarationKind][context 1] Can't augment a method with a field.
// ^^^
// [diag.duplicateDefinition][context 2] The name 'foo' is already defined.
}
''');
}
@@ -281,7 +278,6 @@ class A {
A.foo();
// ^^^
// [context 1] The declaration being augmented.
// [diag.conflictingConstructorAndStaticField] 'foo' can't be used to name both a constructor and a static field in this class.
}
augment class A {
augment static int foo = 0;
@@ -297,14 +293,11 @@ class A {
static void foo() {}
// ^^^
// [context 1] The declaration being augmented.
// [context 2] The first definition of this name.
}
augment class A {
augment static int foo = 0;
//^^^^^^^
// [diag.augmentationOfDifferentDeclarationKind][context 1] Can't augment a method with a field.
// ^^^
// [diag.duplicateDefinition][context 2] The name 'foo' is already defined.
}
''');
}
@@ -113,8 +113,6 @@ augment class A {
await resolveTestCodeWithDiagnostics(r'''
class A {
static int foo = 0;
// ^^^
// [diag.conflictingStaticAndInstance] Class 'A' can't define static member 'foo' and have instance member 'A.foo' with the same name.
}
augment class A {
augment int foo = 0;
@@ -128,8 +126,6 @@ augment class A {
await resolveTestCodeWithDiagnostics(r'''
class A {
static int get foo => 0;
// ^^^
// [diag.conflictingStaticAndInstance] Class 'A' can't define static member 'foo' and have instance member 'A.foo' with the same name.
}
augment class A {
augment int foo = 0;
@@ -143,8 +139,6 @@ augment class A {
await resolveTestCodeWithDiagnostics(r'''
class A {
static void foo() {}
// ^^^
// [diag.conflictingStaticAndInstance] Class 'A' can't define static member 'foo' and have instance member 'A.foo' with the same name.
}
augment class A {
augment int foo = 0;
@@ -158,8 +152,6 @@ augment class A {
await resolveTestCodeWithDiagnostics(r'''
class A {
static set foo(int _) {}
// ^^^
// [diag.conflictingStaticAndInstance] Class 'A' can't define static member 'foo' and have instance member 'A.foo' with the same name.
}
augment class A {
augment int foo = 0;
File diff suppressed because it is too large Load Diff