Skip to content

Commit ae6bdae

Browse files
FMorschelCommit Queue
authored andcommitted
[DAS] Fixes create method for enums and extension types
Fixes: #60562 Change-Id: I8bbc92205f5900c025e9dc31110f3e1cb2343643 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423240 Reviewed-by: Samuel Rawlins <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Auto-Submit: Felipe Morschel <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
1 parent aab4777 commit ae6bdae

File tree

5 files changed

+200
-14
lines changed

5 files changed

+200
-14
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ class CreateMethod extends ResolvedCorrectionProducer {
150150
} else if (targetClassElement is ExtensionTypeElement2) {
151151
var fragment = targetClassElement.firstFragment;
152152
targetNode = await getExtensionTypeDeclaration(fragment);
153+
} else if (targetClassElement is EnumElement2) {
154+
var fragment = targetClassElement.firstFragment;
155+
targetNode = await getEnumDeclaration(fragment);
153156
}
154157
if (targetNode == null) {
155158
return;
@@ -158,6 +161,7 @@ class CreateMethod extends ResolvedCorrectionProducer {
158161
if (target is Identifier) {
159162
staticModifier =
160163
target.element?.kind == ElementKind.CLASS ||
164+
target.element?.kind == ElementKind.ENUM ||
161165
target.element?.kind == ElementKind.EXTENSION_TYPE ||
162166
target.element?.kind == ElementKind.MIXIN;
163167
}

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
3636

3737
@override
3838
Future<void> compute(ChangeBuilder builder) async {
39+
var isStatic = false;
3940
var nameNode = node;
4041
if (nameNode is SimpleIdentifier) {
4142
// prepare argument expression (to get parameter)
@@ -47,6 +48,13 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
4748
if (targetType is InterfaceType) {
4849
targetElement = targetType.element3;
4950
argument = target.parent as Expression;
51+
} else if (target case SimpleIdentifier(
52+
:InterfaceElement2? element,
53+
:Expression parent,
54+
)) {
55+
isStatic = true;
56+
targetElement = element;
57+
argument = parent;
5058
} else {
5159
return;
5260
}
@@ -107,7 +115,12 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
107115
}
108116
// add proposal
109117
if (targetElement != null) {
110-
await _createMethod(builder, targetElement, parameterType);
118+
await _createMethod(
119+
builder,
120+
targetElement,
121+
parameterType,
122+
isStatic: isStatic,
123+
);
111124
} else {
112125
await _createFunction(builder, parameterType);
113126
}
@@ -195,8 +208,9 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
195208
Future<void> _createMethod(
196209
ChangeBuilder builder,
197210
InterfaceElement2 targetClassElement,
198-
FunctionType functionType,
199-
) async {
211+
FunctionType functionType, {
212+
required bool isStatic,
213+
}) async {
200214
var name = (node as SimpleIdentifier).name;
201215
// prepare environment
202216
var targetSource = targetClassElement.firstFragment.libraryFragment.source;
@@ -211,6 +225,14 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
211225
var fragment = targetClassElement.firstFragment;
212226
var node = targetNode = await getClassDeclaration(fragment);
213227
classMembers = node?.members;
228+
} else if (targetClassElement is ExtensionTypeElement2) {
229+
var fragment = targetClassElement.firstFragment;
230+
var node = targetNode = await getExtensionTypeDeclaration(fragment);
231+
classMembers = node?.members;
232+
} else if (targetClassElement is EnumElement2) {
233+
var fragment = targetClassElement.firstFragment;
234+
var node = targetNode = await getEnumDeclaration(fragment);
235+
classMembers = node?.members;
214236
}
215237
if (targetNode == null || classMembers == null) {
216238
return;
@@ -231,7 +253,7 @@ class CreateMethodOrFunction extends ResolvedCorrectionProducer {
231253
name,
232254
targetSource.fullName,
233255
insertOffset,
234-
inStaticContext,
256+
isStatic || inStaticContext,
235257
prefix,
236258
sourcePrefix,
237259
sourceSuffix,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,7 @@ final _builtInNonLintGenerators = <ErrorCode, List<ProducerGenerator>>{
965965
CompileTimeErrorCode.UNDEFINED_ENUM_CONSTANT: [
966966
AddEnumConstant.new,
967967
ChangeTo.getterOrSetter,
968+
CreateMethodOrFunction.new,
968969
],
969970
CompileTimeErrorCode.UNDEFINED_ENUM_CONSTRUCTOR_NAMED: [
970971
CreateConstructor.new,

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

Lines changed: 158 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,164 @@ class A {
728728
''');
729729
}
730730

731+
Future<void> test_enum_invocation() async {
732+
await resolveTestCode('''
733+
enum E {
734+
e1,
735+
e2;
736+
}
737+
738+
void test(E e) {
739+
e.bar();
740+
}
741+
''');
742+
await assertHasFix('''
743+
enum E {
744+
e1,
745+
e2;
746+
747+
void bar() {}
748+
}
749+
750+
void test(E e) {
751+
e.bar();
752+
}
753+
''');
754+
}
755+
756+
Future<void> test_enum_invocation_static() async {
757+
await resolveTestCode('''
758+
enum E {
759+
e1,
760+
e2;
761+
}
762+
763+
void test() {
764+
E.bar();
765+
}
766+
''');
767+
await assertHasFix('''
768+
enum E {
769+
e1,
770+
e2;
771+
772+
static void bar() {}
773+
}
774+
775+
void test() {
776+
E.bar();
777+
}
778+
''');
779+
}
780+
781+
Future<void> test_enum_tearoff() async {
782+
await resolveTestCode('''
783+
enum E {
784+
e1,
785+
e2;
786+
}
787+
788+
void g(int Function() f) {}
789+
790+
void test(E e) {
791+
g(e.bar);
792+
}
793+
''');
794+
await assertHasFix('''
795+
enum E {
796+
e1,
797+
e2;
798+
int bar() {
799+
}
800+
}
801+
802+
void g(int Function() f) {}
803+
804+
void test(E e) {
805+
g(e.bar);
806+
}
807+
''');
808+
}
809+
810+
Future<void> test_enum_tearoff_static() async {
811+
await resolveTestCode('''
812+
enum E {
813+
e1,
814+
e2;
815+
}
816+
817+
void g(int Function() f) {}
818+
819+
void test() {
820+
g(E.bar);
821+
}
822+
''');
823+
await assertHasFix('''
824+
enum E {
825+
e1,
826+
e2;
827+
static int bar() {
828+
}
829+
}
830+
831+
void g(int Function() f) {}
832+
833+
void test() {
834+
g(E.bar);
835+
}
836+
''');
837+
}
838+
839+
Future<void> test_extensionType_tearoff() async {
840+
await resolveTestCode('''
841+
extension type E(int i) {
842+
}
843+
844+
void g(int Function() f) {}
845+
846+
void test(E e) {
847+
g(e.bar);
848+
}
849+
''');
850+
await assertHasFix('''
851+
extension type E(int i) {
852+
int bar() {
853+
}
854+
}
855+
856+
void g(int Function() f) {}
857+
858+
void test(E e) {
859+
g(e.bar);
860+
}
861+
''');
862+
}
863+
864+
Future<void> test_extensionType_tearoff_static() async {
865+
await resolveTestCode('''
866+
extension type E(int i) {
867+
}
868+
869+
void g(int Function() f) {}
870+
871+
void test() {
872+
g(E.bar);
873+
}
874+
''');
875+
await assertHasFix('''
876+
extension type E(int i) {
877+
static int bar() {
878+
}
879+
}
880+
881+
void g(int Function() f) {}
882+
883+
void test() {
884+
g(E.bar);
885+
}
886+
''');
887+
}
888+
731889
Future<void> test_functionType_argument() async {
732890
await resolveTestCode('''
733891
class A {
@@ -1465,14 +1623,4 @@ void f() {
14651623
}
14661624
''');
14671625
}
1468-
1469-
Future<void> test_targetIsEnum() async {
1470-
await resolveTestCode('''
1471-
enum MyEnum {A, B}
1472-
void f() {
1473-
MyEnum.foo();
1474-
}
1475-
''');
1476-
await assertNoFix();
1477-
}
14781626
}

pkg/analysis_server_plugin/lib/edit/dart/correction_producer.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,17 @@ abstract class ResolvedCorrectionProducer
429429
return null;
430430
}
431431

432+
/// Returns the class declaration for the given [fragment], or `null` if there
433+
/// is no such class.
434+
Future<EnumDeclaration?> getEnumDeclaration(EnumFragment fragment) async {
435+
var result = await sessionHelper.getFragmentDeclaration(fragment);
436+
var node = result?.node;
437+
if (node is EnumDeclaration) {
438+
return node;
439+
}
440+
return null;
441+
}
442+
432443
/// Returns the extension declaration for the given [fragment], or `null` if
433444
/// there is no such extension.
434445
Future<ExtensionDeclaration?> getExtensionDeclaration(

0 commit comments

Comments
 (0)