Skip to content

Commit ad7f786

Browse files
kallentuCommit Queue
authored andcommitted
[analysis_server] Dot shorthands: Update CreateGetter and CreateField.
`CreateGetter` and `CreateField` are now two available fixes for dot shorthand property accesses. Updated each fix to handle dot shorthands using the computed context type element and added tests. Bug: #60994 Change-Id: I6b21c8034521503eae6c490597a1b3894acb489c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/442247 Commit-Queue: Kallen Tu <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 86d3c73 commit ad7f786

File tree

6 files changed

+166
-11
lines changed

6 files changed

+166
-11
lines changed

pkg/analysis_server/lib/src/services/correction/dart/create_field.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ class CreateField extends CreateFieldOrGetter {
146146
}
147147
_fieldName = nameNode.name;
148148
// Prepare target `Expression`.
149-
var target = switch (nameNode.parent) {
149+
var parent = nameNode.parent;
150+
var target = switch (parent) {
150151
PrefixedIdentifier(:var prefix) => prefix,
151152
PropertyAccess(:var realTarget) => realTarget,
152153
_ => null,
@@ -165,6 +166,12 @@ class CreateField extends CreateFieldOrGetter {
165166
}
166167
staticModifier = targetElement.kind == ElementKind.CLASS;
167168
}
169+
} else if (parent is DotShorthandPropertyAccess) {
170+
targetClassElement = computeDotShorthandContextTypeElement(
171+
node,
172+
unitResult.libraryElement,
173+
);
174+
staticModifier = true;
168175
} else {
169176
targetClassElement = node.enclosingInterfaceElement;
170177
staticModifier = inStaticContext;

pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,13 @@ class CreateGetter extends CreateFieldOrGetter {
132132
}
133133
// prepare target
134134
Expression? target;
135-
{
136-
var nameParent = nameNode.parent;
137-
if (nameParent is PrefixedIdentifier) {
138-
target = nameParent.prefix;
139-
} else if (nameParent is PropertyAccess) {
140-
target = nameParent.realTarget;
141-
}
135+
var nameParent = nameNode.parent;
136+
if (nameParent is PrefixedIdentifier) {
137+
target = nameParent.prefix;
138+
} else if (nameParent is PropertyAccess) {
139+
target = nameParent.realTarget;
142140
}
141+
143142
// prepare target element
144143
var staticModifier = false;
145144
InstanceElement? targetElement;
@@ -161,6 +160,12 @@ class CreateGetter extends CreateFieldOrGetter {
161160
var targetElement = targetIdentifier.element;
162161
staticModifier = targetElement?.kind == ElementKind.CLASS;
163162
}
163+
} else if (nameParent is DotShorthandPropertyAccess) {
164+
staticModifier = true;
165+
targetElement = computeDotShorthandContextTypeElement(
166+
node,
167+
unitResult.libraryElement,
168+
);
164169
} else {
165170
staticModifier = inStaticContext;
166171
targetElement = nameNode.enclosingInstanceElement;

pkg/analysis_server/lib/src/services/correction/fix_internal.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,13 @@ final _builtInNonLintGenerators = <DiagnosticCode, List<ProducerGenerator>>{
628628
],
629629
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_GETTER: [
630630
ChangeTo.getterOrSetter,
631+
CreateGetter.new,
632+
CreateField.new,
633+
],
634+
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION: [
635+
ChangeTo.method,
636+
CreateMethod.method,
631637
],
632-
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION: [ChangeTo.method],
633638
CompileTimeErrorCode.EMPTY_MAP_PATTERN: [
634639
ReplaceEmptyMapPattern.any,
635640
ReplaceEmptyMapPattern.empty,

pkg/analysis_server/lib/src/services/correction/util.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import 'package:analyzer/src/utilities/extensions/ast.dart';
1818
import 'package:analyzer_plugin/utilities/range_factory.dart';
1919
import 'package:path/path.dart' as path;
2020

21-
/// Climbs up [PrefixedIdentifier] and [PropertyAccess] nodes that include
22-
/// [node].
21+
/// Climbs up [PrefixedIdentifier], [PropertyAccess], and
22+
/// [DotShorthandPropertyAccess] nodes that include [node].
2323
Expression climbPropertyAccess(Expression node) {
2424
while (true) {
2525
var parent = node.parent;
@@ -31,6 +31,10 @@ Expression climbPropertyAccess(Expression node) {
3131
node = parent;
3232
continue;
3333
}
34+
if (parent is DotShorthandPropertyAccess && parent.propertyName == node) {
35+
node = parent;
36+
continue;
37+
}
3438
return node;
3539
}
3640
}

pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,29 @@ int f(E e) {
101101
''');
102102
}
103103

104+
Future<void> test_usedAsGetter_dotShorthand() async {
105+
await resolveTestCode('''
106+
enum E {
107+
one, two;
108+
}
109+
110+
E f() {
111+
return .a;
112+
}
113+
''');
114+
await assertHasFix('''
115+
enum E {
116+
one, two;
117+
118+
static final E a;
119+
}
120+
121+
E f() {
122+
return .a;
123+
}
124+
''');
125+
}
126+
104127
Future<void> test_usedAsSetter() async {
105128
await resolveTestCode('''
106129
enum E {
@@ -120,6 +143,25 @@ class CreateFieldMixinTest extends FixProcessorTest {
120143
@override
121144
FixKind get kind => DartFixKind.CREATE_FIELD;
122145

146+
Future<void> test_dotShorthand() async {
147+
await resolveTestCode('''
148+
mixin A {}
149+
void f() {
150+
A v = .test;
151+
print(v);
152+
}
153+
''');
154+
await assertHasFix('''
155+
mixin A {
156+
static A test;
157+
}
158+
void f() {
159+
A v = .test;
160+
print(v);
161+
}
162+
''');
163+
}
164+
123165
Future<void> test_getter_qualified_instance() async {
124166
await resolveTestCode('''
125167
mixin M {
@@ -177,6 +219,36 @@ class CreateFieldTest extends FixProcessorTest {
177219
@override
178220
FixKind get kind => DartFixKind.CREATE_FIELD;
179221

222+
Future<void> test_dotShorthand_class() async {
223+
await resolveTestCode('''
224+
class A {}
225+
void f() {
226+
A v = .test;
227+
print(v);
228+
}
229+
''');
230+
await assertHasFix('''
231+
class A {
232+
static A test;
233+
}
234+
void f() {
235+
A v = .test;
236+
print(v);
237+
}
238+
''');
239+
}
240+
241+
Future<void> test_dotShorthand_extensionType() async {
242+
await resolveTestCode('''
243+
extension type A(int x) {}
244+
void f() {
245+
A v = .test;
246+
print(v);
247+
}
248+
''');
249+
await assertNoFix();
250+
}
251+
180252
Future<void> test_getter_multiLevel() async {
181253
await resolveTestCode('''
182254
class A {

pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,28 @@ class CreateGetterMixinTest extends FixProcessorTest {
2020
@override
2121
FixKind get kind => DartFixKind.CREATE_GETTER;
2222

23+
Future<void> test_dotShorthand() async {
24+
await resolveTestCode('''
25+
mixin M {
26+
}
27+
28+
void f() {
29+
M v = .test;
30+
print(v);
31+
}
32+
''');
33+
await assertHasFix('''
34+
mixin M {
35+
static M get test => null;
36+
}
37+
38+
void f() {
39+
M v = .test;
40+
print(v);
41+
}
42+
''');
43+
}
44+
2345
Future<void> test_inExtensionGetter() async {
2446
await resolveTestCode('''
2547
mixin M {
@@ -179,6 +201,46 @@ class CreateGetterTest extends FixProcessorTest {
179201
@override
180202
FixKind get kind => DartFixKind.CREATE_GETTER;
181203

204+
Future<void> test_dotShorthand_class() async {
205+
await resolveTestCode('''
206+
class A {
207+
}
208+
void f() {
209+
A v = .getter;
210+
print(v);
211+
}
212+
''');
213+
await assertHasFix('''
214+
class A {
215+
static A get getter => null;
216+
}
217+
void f() {
218+
A v = .getter;
219+
print(v);
220+
}
221+
''');
222+
}
223+
224+
Future<void> test_dotShorthand_extensionType() async {
225+
await resolveTestCode('''
226+
extension type A(int i) {
227+
}
228+
void f() {
229+
A v = .getter;
230+
print(v);
231+
}
232+
''');
233+
await assertHasFix('''
234+
extension type A(int i) {
235+
static A get getter => null;
236+
}
237+
void f() {
238+
A v = .getter;
239+
print(v);
240+
}
241+
''');
242+
}
243+
182244
Future<void> test_extension_type() async {
183245
await resolveTestCode('''
184246
extension type A(String s) {

0 commit comments

Comments
 (0)