Issue 52059. Don't suggest final/var in ObjectPattern in ForEachPartsWithPattern, suggest getters instead.
Bug: https://github.com/dart-lang/sdk/issues/52059
Change-Id: If5e1c40fa75735077b2b77a5941d16fe2c767f3e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/296501
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/services/completion/dart/location/object_pattern_test.dart b/pkg/analysis_server/test/services/completion/dart/location/object_pattern_test.dart
index 9c1abcf..3c03948 100644
--- a/pkg/analysis_server/test/services/completion/dart/location/object_pattern_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/location/object_pattern_test.dart
@@ -123,6 +123,192 @@
}
Future<void>
+ test_forEachPartsWithPattern_first_afterColon_withoutGetter() async {
+ await computeSuggestions('''
+void f1(List<A1> x0) {
+ for (final A1(: ^) in x0) {}
+}
+class A0 {
+ int f01 = 0;
+ int get g01 => 0;
+ set s01(x) {}
+ int m01() => 0;
+ static int f02 = 0;
+ static int get g02 => 0;
+ static int m02() => 0;
+ static set s02(x) {}
+}
+class A1 extends A0 {
+ int f11 = 0;
+ int get g11 => 0;
+ set s11(x) {}
+ int m11() => 0;
+ static int f12 = 0;
+ static int get g12 => 0;
+ static int m12() => 0;
+ static set s12(x) {}
+}
+''');
+ assertResponse(r'''
+suggestions
+ f01
+ kind: field
+ f11
+ kind: field
+ g01
+ kind: getter
+ g11
+ kind: getter
+''');
+ }
+
+ Future<void>
+ test_forEachPartsWithPattern_first_afterColon_withoutGetter_partial() async {
+ await computeSuggestions('''
+void f1(List<A1> x0) {
+ for (final A1(: g^) in x0) {}
+}
+class A0 {
+ int f01 = 0;
+ int get g01 => 0;
+ set s01(x) {}
+ int m01() => 0;
+ static int f02 = 0;
+ static int get g02 => 0;
+ static int m02() => 0;
+ static set s02(x) {}
+}
+class A1 extends A0 {
+ int f11 = 0;
+ int get g11 => 0;
+ set s11(x) {}
+ int m11() => 0;
+ static int f12 = 0;
+ static int get g12 => 0;
+ static int m12() => 0;
+ static set s12(x) {}
+}
+''');
+ if (isProtocolVersion2) {
+ assertResponse(r'''
+replacement
+ left: 1
+suggestions
+ g01
+ kind: getter
+ g11
+ kind: getter
+''');
+ } else {
+ assertResponse(r'''
+replacement
+ left: 1
+suggestions
+ f01
+ kind: field
+ f11
+ kind: field
+ g01
+ kind: getter
+ g11
+ kind: getter
+''');
+ }
+ }
+
+ Future<void> test_forEachPartsWithPattern_first_beforeColon() async {
+ await computeSuggestions('''
+void f1(List<A1> x0) {
+ for (final A1(^:) in x0) {}
+}
+class A0 {
+ int f01 = 0;
+ int get g01 => 0;
+ set s01(x) {}
+ int m01() => 0;
+ static int f02 = 0;
+ static int get g02 => 0;
+ static int m02() => 0;
+ static set s02(x) {}
+}
+class A1 extends A0 {
+ int f11 = 0;
+ int get g11 => 0;
+ set s11(x) {}
+ int m11() => 0;
+ static int f12 = 0;
+ static int get g12 => 0;
+ static int m12() => 0;
+ static set s12(x) {}
+}
+''');
+ assertResponse(r'''
+suggestions
+ f01
+ kind: field
+ f11
+ kind: field
+ g01
+ kind: getter
+ g11
+ kind: getter
+''');
+ }
+
+ Future<void> test_forEachPartsWithPattern_first_beforeColon_partial() async {
+ await computeSuggestions('''
+void f1(List<A1> x0) {
+ for (final A1(g^:) in x0) {}
+}
+class A0 {
+ int f01 = 0;
+ int get g01 => 0;
+ set s01(x) {}
+ int m01() => 0;
+ static int f02 = 0;
+ static int get g02 => 0;
+ static int m02() => 0;
+ static set s02(x) {}
+}
+class A1 extends A0 {
+ int f11 = 0;
+ int get g11 => 0;
+ set s11(x) {}
+ int m11() => 0;
+ static int f12 = 0;
+ static int get g12 => 0;
+ static int m12() => 0;
+ static set s12(x) {}
+}
+''');
+ if (isProtocolVersion2) {
+ assertResponse(r'''
+replacement
+ left: 1
+suggestions
+ g01
+ kind: getter
+ g11
+ kind: getter
+''');
+ } else {
+ assertResponse(r'''
+replacement
+ left: 1
+suggestions
+ f01
+ kind: field
+ f11
+ kind: field
+ g01
+ kind: getter
+ g11
+ kind: getter
+''');
+ }
+ }
+
+ Future<void>
test_matchingContext_pattern_first_withoutGetter_afterColon() async {
await computeSuggestions('''
void f1(Object x0) {
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 31224db3..cd3e714 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -3460,7 +3460,9 @@
DartType? matchedValueType;
/// Returns the context for this pattern.
- /// * Declaration context: [PatternVariableDeclarationImpl]
+ /// * Declaration context:
+ /// [ForEachPartsWithPatternImpl]
+ /// [PatternVariableDeclarationImpl]
/// * Assignment context: [PatternAssignmentImpl]
/// * Matching context: [GuardedPatternImpl]
AstNodeImpl? get patternContext {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 98055b9..71e5338 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -1753,6 +1753,7 @@
final pattern = node.pattern;
final patternContext = pattern.patternContext;
if (pattern is DeclaredVariablePatternImpl ||
+ patternContext is ForEachPartsWithPattern ||
patternContext is PatternVariableDeclaration) {
optype.patternLocation = NamedPatternFieldWantsName(
matchedType: parentMatchedValueType,