From 8aa120576b30a7fa68c8ff18009718a3b17e24fe Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Tue, 7 Jan 2020 03:12:29 +0100 Subject: [PATCH] Add quick fix for TOPLEVEL_TYPEALIASES_ONLY --- .../messages/KotlinBundle.properties | 3 +- .../quickfix/MoveTypeAliasToTopLevelFix.kt | 35 +++++++++++++++++++ .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 2 ++ .../moveTypeAliasToTopLevel/inClass.kt | 9 +++++ .../moveTypeAliasToTopLevel/inClass.kt.after | 10 ++++++ .../moveTypeAliasToTopLevel/inClass2.kt | 11 ++++++ .../moveTypeAliasToTopLevel/inClass2.kt.after | 12 +++++++ .../moveTypeAliasToTopLevel/inFunction.kt | 9 +++++ .../inFunction.kt.after | 10 ++++++ .../moveTypeAliasToTopLevel/inFunction2.kt | 11 ++++++ .../inFunction2.kt.after | 12 +++++++ .../QuickFixMultiFileTestGenerated.java | 13 +++++++ .../idea/quickfix/QuickFixTestGenerated.java | 33 +++++++++++++++++ 13 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeAliasToTopLevelFix.kt create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt.after create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt.after create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt.after create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt create mode 100644 idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt.after diff --git a/idea/resources/messages/KotlinBundle.properties b/idea/resources/messages/KotlinBundle.properties index e7b0926c41e..871c9431ff6 100644 --- a/idea/resources/messages/KotlinBundle.properties +++ b/idea/resources/messages/KotlinBundle.properties @@ -2195,4 +2195,5 @@ move.refactoring.error.text.cannot.perform.refactoring.since.the.following.files kotlin.script.definitions.model.name.is.enabled=Is Enabled kotlin.script.definitions.model.name.pattern.extension=Pattern/Extension kotlin.script.definitions.model.name.name=Name -codestyle.name.kotlin=Kotlin \ No newline at end of file +codestyle.name.kotlin=Kotlin +fix.move.typealias.to.top.level=Move typealias to top level \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeAliasToTopLevelFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeAliasToTopLevelFix.kt new file mode 100644 index 00000000000..81e141f4d11 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeAliasToTopLevelFix.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.quickfix + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.KtTypeAlias +import org.jetbrains.kotlin.psi.psiUtil.parents + +class MoveTypeAliasToTopLevelFix(element: KtTypeAlias) : KotlinQuickFixAction(element) { + override fun getText() = KotlinBundle.message("fix.move.typealias.to.top.level") + + override fun getFamilyName() = text + + override fun invoke(project: Project, editor: Editor?, file: KtFile) { + val typeAlias = element ?: return + val parents = typeAlias.parents.toList().reversed() + val containingFile = parents.firstOrNull() as? KtFile ?: return + val target = parents.getOrNull(1) ?: return + containingFile.addAfter(typeAlias, target) + containingFile.addAfter(KtPsiFactory(typeAlias).createNewLine(2), target) + typeAlias.delete() + } + + companion object : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic) = (diagnostic.psiElement as? KtTypeAlias)?.let { MoveTypeAliasToTopLevelFix(it) } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 25e45dfb573..d8c7764cdae 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -644,5 +644,7 @@ class QuickFixRegistrar : QuickFixContributor { TOO_MANY_ARGUMENTS.registerFactory(RemoveArgumentFix) FUN_INTERFACE_WRONG_COUNT_OF_ABSTRACT_MEMBERS.registerFactory(RemoveModifierFix.createRemoveFunFromInterfaceFactory()) + + TOPLEVEL_TYPEALIASES_ONLY.registerFactory(MoveTypeAliasToTopLevelFix) } } diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt new file mode 100644 index 00000000000..a94bbb16108 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt @@ -0,0 +1,9 @@ +// "Move typealias to top level" "true" +class C { + typealias Foo = String + + fun bar(foo: Foo) { + } +} + +fun baz() {} \ No newline at end of file diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt.after b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt.after new file mode 100644 index 00000000000..6df86a283f6 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt.after @@ -0,0 +1,10 @@ +// "Move typealias to top level" "true" +class C { + + fun bar(foo: Foo) { + } +} + +typealias Foo = String + +fun baz() {} \ No newline at end of file diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt new file mode 100644 index 00000000000..8af40e1d576 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt @@ -0,0 +1,11 @@ +// "Move typealias to top level" "true" +class C { + class CC { + typealias Foo = String + + fun bar(foo: Foo) { + } + } +} + +fun baz() {} \ No newline at end of file diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt.after b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt.after new file mode 100644 index 00000000000..f86e07c7323 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt.after @@ -0,0 +1,12 @@ +// "Move typealias to top level" "true" +class C { + class CC { + + fun bar(foo: Foo) { + } + } +} + +typealias Foo = String + +fun baz() {} \ No newline at end of file diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt new file mode 100644 index 00000000000..c3615541709 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt @@ -0,0 +1,9 @@ +// "Move typealias to top level" "true" +fun bar() { + typealias Foo = String + + fun baz(foo: Foo) { + } +} + +fun qux() {} \ No newline at end of file diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt.after b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt.after new file mode 100644 index 00000000000..6739b0a9b64 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt.after @@ -0,0 +1,10 @@ +// "Move typealias to top level" "true" +fun bar() { + + fun baz(foo: Foo) { + } +} + +typealias Foo = String + +fun qux() {} \ No newline at end of file diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt new file mode 100644 index 00000000000..13e9cd50c16 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt @@ -0,0 +1,11 @@ +// "Move typealias to top level" "true" +fun bar() { + class C { + typealias Foo = String + + fun baz(foo: Foo) { + } + } +} + +fun qux() {} \ No newline at end of file diff --git a/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt.after b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt.after new file mode 100644 index 00000000000..29b30fbaf01 --- /dev/null +++ b/idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt.after @@ -0,0 +1,12 @@ +// "Move typealias to top level" "true" +fun bar() { + class C { + + fun baz(foo: Foo) { + } + } +} + +typealias Foo = String + +fun qux() {} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index ed3a3361ba6..1eb96ed6893 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -3443,6 +3443,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } } + @TestMetadata("idea/testData/quickfix/moveTypeAliasToTopLevel") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MoveTypeAliasToTopLevel extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, this, testDataFilePath); + } + + public void testAllFilesPresentInMoveTypeAliasToTopLevel() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/moveTypeAliasToTopLevel"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), null, true); + } + } + @TestMetadata("idea/testData/quickfix/nullables") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 6526a79a578..675afddc91f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -9508,6 +9508,39 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/moveTypeAliasToTopLevel") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MoveTypeAliasToTopLevel extends AbstractQuickFixTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInMoveTypeAliasToTopLevel() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/moveTypeAliasToTopLevel"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); + } + + @TestMetadata("inClass.kt") + public void testInClass() throws Exception { + runTest("idea/testData/quickfix/moveTypeAliasToTopLevel/inClass.kt"); + } + + @TestMetadata("inClass2.kt") + public void testInClass2() throws Exception { + runTest("idea/testData/quickfix/moveTypeAliasToTopLevel/inClass2.kt"); + } + + @TestMetadata("inFunction.kt") + public void testInFunction() throws Exception { + runTest("idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction.kt"); + } + + @TestMetadata("inFunction2.kt") + public void testInFunction2() throws Exception { + runTest("idea/testData/quickfix/moveTypeAliasToTopLevel/inFunction2.kt"); + } + } + @TestMetadata("idea/testData/quickfix/nullables") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)