33// BSD-style license that can be found in the LICENSE file.
44
55import 'package:analysis_server/src/services/correction/fix.dart' ;
6+ import 'package:analysis_server/src/services/correction/util.dart' ;
67import 'package:analysis_server_plugin/edit/dart/correction_producer.dart' ;
78import 'package:analyzer/dart/analysis/results.dart' ;
89import '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,
0 commit comments