Skip to content

Commit 50c1087

Browse files
kallentuCommit Queue
authored andcommitted
[analysis_server] Dot shorthands: Update CreateConstructor.
Update the fix to allow creating constructors in class declarations from an unresolved dot shorthand invocation. Bug: #60994 Change-Id: Id3c58ac0b2c1963d29c875739afa19f0fc4bbd7a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/443185 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
1 parent 26060ed commit 50c1087

File tree

3 files changed

+262
-77
lines changed

3 files changed

+262
-77
lines changed

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

Lines changed: 129 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analysis_server/src/services/correction/fix.dart';
6+
import 'package:analysis_server/src/services/correction/util.dart';
67
import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
78
import 'package:analyzer/dart/analysis/results.dart';
89
import 'package:analyzer/dart/ast/ast.dart';
@@ -36,16 +37,34 @@ class CreateConstructor extends ResolvedCorrectionProducer {
3637
var node = this.node;
3738
var argumentList = node.parent is ArgumentList ? node.parent : node;
3839
if (argumentList is ArgumentList) {
39-
var instanceCreation = argumentList.parent;
40-
if (instanceCreation is InstanceCreationExpression) {
41-
await _proposeFromInstanceCreation(builder, instanceCreation);
40+
var constructorInvocation = argumentList.parent;
41+
if (constructorInvocation is InstanceCreationExpression) {
42+
await _proposeFromConstructorInvocation(
43+
builder,
44+
constructorInvocation,
45+
constructorInvocation.constructorName.element,
46+
constructorInvocation.argumentList,
47+
);
48+
} else if (constructorInvocation is DotShorthandConstructorInvocation) {
49+
await _proposeFromConstructorInvocation(
50+
builder,
51+
constructorInvocation,
52+
constructorInvocation.element,
53+
constructorInvocation.argumentList,
54+
);
4255
}
4356
} else {
4457
if (node is SimpleIdentifier) {
4558
var parent = node.parent;
4659
if (parent is ConstructorName) {
4760
await _proposeFromConstructorName(builder, node.token, parent);
4861
return;
62+
} else if (parent is DotShorthandInvocation) {
63+
return await _proposeFromDotShorthandInvocation(
64+
builder,
65+
node.token,
66+
parent,
67+
);
4968
}
5069
}
5170
var parent = node.thisOrAncestorOfType<EnumConstantDeclaration>();
@@ -55,6 +74,93 @@ class CreateConstructor extends ResolvedCorrectionProducer {
5574
}
5675
}
5776

77+
/// Common logic for building and writing a constructor from a
78+
/// [ConstructorName] or a [DotShorthandInvocation].
79+
Future<void> _finishCreatingConstructor(
80+
ChangeBuilder builder,
81+
InterfaceElement targetElement,
82+
Token name,
83+
ArgumentList? argumentList,
84+
) async {
85+
var targetFragment = targetElement.firstFragment;
86+
var targetResult = await sessionHelper.getFragmentDeclaration(
87+
targetFragment,
88+
);
89+
if (targetResult == null) {
90+
return;
91+
}
92+
var targetNode = targetResult.node;
93+
if (targetNode is! ClassDeclaration) {
94+
return;
95+
}
96+
97+
var resolvedUnit = targetResult.resolvedUnit;
98+
if (resolvedUnit == null) {
99+
return;
100+
}
101+
102+
await _write(
103+
builder,
104+
resolvedUnit,
105+
name,
106+
targetNode,
107+
constructorName: name,
108+
argumentList: argumentList,
109+
);
110+
}
111+
112+
Future<void> _proposeFromConstructorInvocation(
113+
ChangeBuilder builder,
114+
AstNode node,
115+
ConstructorElement? constructorElement,
116+
ArgumentList argumentList,
117+
) async {
118+
_constructorName = node.toSource();
119+
// should be synthetic default constructor
120+
if (constructorElement == null ||
121+
!constructorElement.isDefaultConstructor ||
122+
!constructorElement.isSynthetic) {
123+
return;
124+
}
125+
126+
var targetElement = constructorElement.enclosingElement;
127+
if (targetElement is! ClassElement) return;
128+
var targetFragment = targetElement.firstFragment;
129+
130+
var targetElementName = targetElement.name;
131+
if (targetElementName == null) {
132+
return;
133+
}
134+
135+
// prepare target ClassDeclaration
136+
var targetResult = await sessionHelper.getFragmentDeclaration(
137+
targetFragment,
138+
);
139+
if (targetResult == null) {
140+
return;
141+
}
142+
var targetNode = targetResult.node;
143+
if (targetNode is! ClassDeclaration) {
144+
return;
145+
}
146+
147+
var resolvedUnit = targetResult.resolvedUnit;
148+
if (resolvedUnit == null) {
149+
return;
150+
}
151+
152+
var targetSource = targetFragment.libraryFragment.source;
153+
var targetFile = targetSource.fullName;
154+
await builder.addDartFileEdit(targetFile, (builder) {
155+
builder.insertConstructor(targetNode, (builder) {
156+
builder.writeConstructorDeclaration(
157+
targetElementName,
158+
argumentList: argumentList,
159+
);
160+
});
161+
});
162+
}
163+
58164
Future<void> _proposeFromConstructorName(
59165
ChangeBuilder builder,
60166
Token name,
@@ -87,30 +193,31 @@ class CreateConstructor extends ResolvedCorrectionProducer {
87193

88194
// prepare target ClassDeclaration
89195
var targetElement = targetType.element;
90-
var targetFragment = targetElement.firstFragment;
91-
var targetResult = await sessionHelper.getFragmentDeclaration(
92-
targetFragment,
196+
await _finishCreatingConstructor(
197+
builder,
198+
targetElement,
199+
name,
200+
instanceCreation.argumentList,
93201
);
94-
if (targetResult == null) {
95-
return;
96-
}
97-
var targetNode = targetResult.node;
98-
if (targetNode is! ClassDeclaration) {
99-
return;
100-
}
202+
}
101203

102-
var resolvedUnit = targetResult.resolvedUnit;
103-
if (resolvedUnit == null) {
104-
return;
105-
}
204+
Future<void> _proposeFromDotShorthandInvocation(
205+
ChangeBuilder builder,
206+
Token name,
207+
DotShorthandInvocation node,
208+
) async {
209+
_constructorName = node.toSource();
210+
var targetElement = computeDotShorthandContextTypeElement(
211+
node,
212+
unitResult.libraryElement,
213+
);
214+
if (targetElement == null) return;
106215

107-
await _write(
216+
await _finishCreatingConstructor(
108217
builder,
109-
resolvedUnit,
218+
targetElement,
110219
name,
111-
targetNode,
112-
constructorName: name,
113-
argumentList: instanceCreation.argumentList,
220+
node.argumentList,
114221
);
115222
}
116223

@@ -161,57 +268,6 @@ class CreateConstructor extends ResolvedCorrectionProducer {
161268
);
162269
}
163270

164-
Future<void> _proposeFromInstanceCreation(
165-
ChangeBuilder builder,
166-
InstanceCreationExpression instanceCreation,
167-
) async {
168-
var constructorName = instanceCreation.constructorName;
169-
_constructorName = constructorName.toSource();
170-
// should be synthetic default constructor
171-
var constructorElement = constructorName.element;
172-
if (constructorElement == null ||
173-
!constructorElement.isDefaultConstructor ||
174-
!constructorElement.isSynthetic) {
175-
return;
176-
}
177-
178-
var targetElement = constructorElement.enclosingElement;
179-
var targetFragment = (targetElement as ClassElement).firstFragment;
180-
181-
var targetElementName = targetElement.name;
182-
if (targetElementName == null) {
183-
return;
184-
}
185-
186-
// prepare target ClassDeclaration
187-
var targetResult = await sessionHelper.getFragmentDeclaration(
188-
targetFragment,
189-
);
190-
if (targetResult == null) {
191-
return;
192-
}
193-
var targetNode = targetResult.node;
194-
if (targetNode is! ClassDeclaration) {
195-
return;
196-
}
197-
198-
var resolvedUnit = targetResult.resolvedUnit;
199-
if (resolvedUnit == null) {
200-
return;
201-
}
202-
203-
var targetSource = targetFragment.libraryFragment.source;
204-
var targetFile = targetSource.fullName;
205-
await builder.addDartFileEdit(targetFile, (builder) {
206-
builder.insertConstructor(targetNode, (builder) {
207-
builder.writeConstructorDeclaration(
208-
targetElementName,
209-
argumentList: instanceCreation.argumentList,
210-
);
211-
});
212-
});
213-
}
214-
215271
Future<void> _write(
216272
ChangeBuilder builder,
217273
ResolvedUnitResult resolvedUnit,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ final _builtInNonLintGenerators = <DiagnosticCode, List<ProducerGenerator>>{
636636
],
637637
CompileTimeErrorCode.DOT_SHORTHAND_UNDEFINED_INVOCATION: [
638638
ChangeTo.method,
639+
CreateConstructor.new,
639640
CreateMethod.method,
640641
],
641642
CompileTimeErrorCode.EMPTY_MAP_PATTERN: [

0 commit comments

Comments
 (0)