Support of KT-11255 Support Move Element Left/Right actions for Kotlin (except for enum entries)
#KT-11255 Fixed
This commit is contained in:
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractCodeInsightActionT
|
||||
import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractGenerateHashCodeAndEqualsActionTest
|
||||
import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractGenerateTestSupportMethodActionTest
|
||||
import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractGenerateToStringActionTest
|
||||
import org.jetbrains.kotlin.idea.codeInsight.moveUpDown.AbstractMoveLeftRightTest
|
||||
import org.jetbrains.kotlin.idea.codeInsight.moveUpDown.AbstractMoveStatementTest
|
||||
import org.jetbrains.kotlin.idea.codeInsight.surroundWith.AbstractSurroundWithTest
|
||||
import org.jetbrains.kotlin.idea.codeInsight.unwrap.AbstractUnwrapRemoveTest
|
||||
@@ -511,6 +512,10 @@ fun main(args: Array<String>) {
|
||||
model("codeInsight/moveUpDown/parametersAndArguments", testMethod = "doTestExpression")
|
||||
}
|
||||
|
||||
testClass<AbstractMoveLeftRightTest>() {
|
||||
model("codeInsight/moveLeftRight")
|
||||
}
|
||||
|
||||
testClass<AbstractInlineTest>() {
|
||||
model("refactoring/inline", pattern = "^(\\w+)\\.kt$")
|
||||
}
|
||||
|
||||
@@ -618,6 +618,8 @@
|
||||
implementation="org.jetbrains.kotlin.idea.codeInsight.upDownMover.KotlinDeclarationMover"
|
||||
order="before jetExpression" />
|
||||
|
||||
<moveLeftRightHandler language="kotlin" implementationClass="org.jetbrains.kotlin.idea.codeInsight.KotlinMoveLeftRightHandler"/>
|
||||
|
||||
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinDeclarationAndAssignmentHandler"/>
|
||||
<joinLinesHandler implementation="org.jetbrains.kotlin.idea.joinLines.JoinBlockIntoSingleStatementHandler"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight
|
||||
|
||||
import com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementLeftRightHandler
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
class KotlinMoveLeftRightHandler : MoveElementLeftRightHandler() {
|
||||
override fun getMovableSubElements(element: PsiElement): Array<PsiElement> {
|
||||
when (element) {
|
||||
is KtParameterList -> return element.parameters.toTypedArray()
|
||||
is KtValueArgumentList -> return element.arguments.toTypedArray()
|
||||
is KtArrayAccessExpression -> return element.indexExpressions.toTypedArray()
|
||||
is KtTypeParameterList -> return element.parameters.toTypedArray()
|
||||
is KtSuperTypeList -> return element.entries.toTypedArray()
|
||||
//TODO
|
||||
// is KtClass -> if (element.isEnum()) return element.declarations.filterIsInstance<KtEnumEntry>().toTypedArray()
|
||||
}
|
||||
|
||||
return emptyArray()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
@A(<caret>1, 2)
|
||||
fun foo() {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
@A(2, <caret>1)
|
||||
fun foo() {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// MOVE: left
|
||||
interface I
|
||||
|
||||
abstract class Base
|
||||
|
||||
class A : I, <caret>Base()
|
||||
@@ -0,0 +1,6 @@
|
||||
// MOVE: left
|
||||
interface I
|
||||
|
||||
abstract class Base
|
||||
|
||||
class A : <caret>Base(), I
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
bar(<caret>1, 2)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
bar(2, <caret>1)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
fun foo() {
|
||||
bar(1, <caret>2)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
fun foo() {
|
||||
bar(<caret>2, 1)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
fun foo(list: List<String>) {
|
||||
bar(1, <caret>*list)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
fun foo(list: List<String>) {
|
||||
bar(<caret>*list, 1)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
bar(<caret>a = 1, b = 2)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
bar(b = 2, <caret>a = 1)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
bar(1, <caret>2, 3)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
bar(1, 3, <caret>2)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
enum class E {
|
||||
B, <caret>A, C
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
enum class E {
|
||||
<caret>A, B, C
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
enum class E {
|
||||
A, C, <caret>B
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
enum class E {
|
||||
A, <caret>B, C
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
enum class E {
|
||||
<caret>B, A, C
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
enum class E {
|
||||
A, <caret>B, C
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// MOVE: right
|
||||
enum class E {
|
||||
A, C, <caret>B;
|
||||
|
||||
fun foo(){}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// MOVE: right
|
||||
enum class E {
|
||||
A, <caret>B, C;
|
||||
|
||||
fun foo(){}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// MOVE: left
|
||||
enum class E {
|
||||
A, C<caret>, B
|
||||
|
||||
;
|
||||
|
||||
fun foo(){}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// MOVE: left
|
||||
enum class E {
|
||||
A, B, C<caret>
|
||||
|
||||
;
|
||||
|
||||
fun foo(){}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: left
|
||||
class A {
|
||||
fun foo(b: Int, <caret>a: Int, c: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: left
|
||||
class A {
|
||||
fun foo(<caret>a: Int, b: Int, c: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: right
|
||||
class A {
|
||||
fun foo(b: Int, <caret>a: Int, c: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: right
|
||||
class A {
|
||||
fun foo(b: Int, c: Int, <caret>a: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: right
|
||||
class A {
|
||||
fun foo(<caret>b: Int, a: Int, c: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: right
|
||||
class A {
|
||||
fun foo(a: Int, <caret>b: Int, c: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: left
|
||||
class A {
|
||||
fun foo(<caret>a: Int, b: Int, c: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// MOVE: left
|
||||
class A {
|
||||
fun foo(<caret>a: Int, b: Int, c: Int) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
x[<caret>1, 2]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: right
|
||||
fun foo() {
|
||||
x[2, <caret>1]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
fun foo(list: List<String>) {
|
||||
list.foldRightIndexed(1, { p1, <caret>p2, p3 -> 1 })
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// MOVE: left
|
||||
fun foo(list: List<String>) {
|
||||
list.foldRightIndexed(1, { <caret>p2, p1, p3 -> 1 })
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// MOVE: right
|
||||
fun <<caret>T1, T2> foo() {
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// MOVE: right
|
||||
fun <T2, <caret>T1> foo() {
|
||||
}
|
||||
+28
-16
@@ -21,13 +21,15 @@ import com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementRightActi
|
||||
import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementDownAction
|
||||
import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementUpAction
|
||||
import com.intellij.codeInsight.editorActions.moveUpDown.StatementUpDownMover
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.actionSystem.Presentation
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
|
||||
import junit.framework.ComparisonFailure
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.formatter.FormatSettingsUtil
|
||||
import org.jetbrains.kotlin.idea.codeInsight.upDownMover.KotlinDeclarationMover
|
||||
import org.jetbrains.kotlin.idea.codeInsight.upDownMover.KotlinExpressionMover
|
||||
@@ -58,8 +60,14 @@ abstract class AbstractMoveStatementTest : AbstractCodeMoverTest() {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractMoveLeftRightTest : AbstractCodeMoverTest() {
|
||||
protected fun doTest(path: String) {
|
||||
doTest(path) { isApplicableExpected, direction -> }
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractCodeMoverTest : LightCodeInsightTestCase() {
|
||||
protected fun doTest(path: String, isApplicableChecker: (isApplicableExpected: Boolean, direction: String) -> Unit = { isApplicableExpected, direction -> }) {
|
||||
protected fun doTest(path: String, isApplicableChecker: (isApplicableExpected: Boolean, direction: String) -> Unit) {
|
||||
configureByFile(path)
|
||||
|
||||
val fileText = FileUtil.loadFile(File(path), true)
|
||||
@@ -79,29 +87,33 @@ abstract class AbstractCodeMoverTest : LightCodeInsightTestCase() {
|
||||
|
||||
isApplicableChecker(isApplicableExpected, direction)
|
||||
|
||||
if (isApplicableExpected) {
|
||||
invokeAndCheck(fileText, path, action)
|
||||
}
|
||||
invokeAndCheck(fileText, path, action, isApplicableExpected)
|
||||
}
|
||||
|
||||
private fun invokeAndCheck(fileText: String, path: String, action: EditorAction) {
|
||||
private fun invokeAndCheck(fileText: String, path: String, action: EditorAction, isApplicableExpected: Boolean) {
|
||||
val codeStyleSettings = FormatSettingsUtil.getSettings()
|
||||
val configurator = FormatSettingsUtil.createConfigurator(fileText, codeStyleSettings)
|
||||
configurator.configureSettings()
|
||||
|
||||
try {
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
action.actionPerformed(LightPlatformCodeInsightTestCase.getEditor(), LightPlatformCodeInsightTestCase.getCurrentEditorDataContext())
|
||||
}
|
||||
val editor = LightPlatformCodeInsightTestCase.getEditor()
|
||||
val dataContext = LightPlatformCodeInsightTestCase.getCurrentEditorDataContext()
|
||||
|
||||
val afterFilePath = path + ".after"
|
||||
try {
|
||||
checkResultByFile(afterFilePath)
|
||||
}
|
||||
catch (e: ComparisonFailure) {
|
||||
KotlinTestUtils.assertEqualsToFile(File(afterFilePath), LightPlatformCodeInsightTestCase.getEditor())
|
||||
}
|
||||
val presentation = Presentation()
|
||||
action.update(editor, presentation, dataContext)
|
||||
TestCase.assertEquals(isApplicableExpected, presentation.isEnabled)
|
||||
|
||||
if (isApplicableExpected) {
|
||||
runWriteAction { action.actionPerformed(editor, dataContext) }
|
||||
|
||||
val afterFilePath = path + ".after"
|
||||
try {
|
||||
checkResultByFile(afterFilePath)
|
||||
}
|
||||
catch (e: ComparisonFailure) {
|
||||
KotlinTestUtils.assertEqualsToFile(File(afterFilePath), editor)
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
codeStyleSettings.clearCodeStyleSettings()
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight.moveUpDown;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("idea/testData/codeInsight/moveLeftRight")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class MoveLeftRightTestGenerated extends AbstractMoveLeftRightTest {
|
||||
public void testAllFilesPresentInMoveLeftRight() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/codeInsight/moveLeftRight"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationParams.kt")
|
||||
public void testAnnotationParams() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/annotationParams.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("basesList.kt")
|
||||
public void testBasesList() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/basesList.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callArgs1.kt")
|
||||
public void testCallArgs1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/callArgs1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callArgs2.kt")
|
||||
public void testCallArgs2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/callArgs2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callArgs3.kt")
|
||||
public void testCallArgs3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/callArgs3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callArgs4.kt")
|
||||
public void testCallArgs4() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/callArgs4.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("callArgs5.kt")
|
||||
public void testCallArgs5() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/callArgs5.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("funParams1.kt")
|
||||
public void testFunParams1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/funParams1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("funParams2.kt")
|
||||
public void testFunParams2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/funParams2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("funParams3.kt")
|
||||
public void testFunParams3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/funParams3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("funParams4.kt")
|
||||
public void testFunParams4() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/funParams4.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("indexArgs.kt")
|
||||
public void testIndexArgs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/indexArgs.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaParams.kt")
|
||||
public void testLambdaParams() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/lambdaParams.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typeArgs.kt")
|
||||
public void testTypeArgs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/moveLeftRight/typeArgs.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user