diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 69dbd2232664..80ca13f10417 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -360,6 +360,8 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/editorActions/GroovyMoveLeftRightHandler.kt b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/editorActions/GroovyMoveLeftRightHandler.kt new file mode 100644 index 000000000000..3a9c68b1a6f5 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/editorActions/GroovyMoveLeftRightHandler.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2000-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.plugins.groovy.codeInsight.editorActions + +import com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementLeftRightHandler +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil.getChildrenOfAnyType +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArgumentList +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression +import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumTypeDefinition +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList + +class GroovyMoveLeftRightHandler : MoveElementLeftRightHandler() { + + override fun getMovableSubElements(element: PsiElement): Array = when (element) { + is GrAnnotationArgumentList -> element.attributes + is GrAnnotationArrayInitializer -> element.initializers + is GrArgumentList -> element.allArguments + is GrEnumTypeDefinition -> element.enumConstants + is GrListOrMap -> getChildrenOfAnyType(element, GrExpression::class.java, GrNamedArgument::class.java).toTypedArray() + is GrModifierList -> element.modifiers + is GrParameterList -> element.parameters + is GrReferenceList -> element.referenceElementsGroovy + is GrTypeArgumentList -> element.typeArgumentElements + is GrTypeParameterList -> element.typeParameters + is GrVariableDeclaration -> element.variables + else -> PsiElement.EMPTY_ARRAY + } +} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/codeInsight/editorActions/GroovyMoveLeftRightHandlerTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/codeInsight/editorActions/GroovyMoveLeftRightHandlerTest.groovy new file mode 100644 index 000000000000..853776de8f59 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/codeInsight/editorActions/GroovyMoveLeftRightHandlerTest.groovy @@ -0,0 +1,131 @@ +/* + * Copyright 2000-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.plugins.groovy.codeInsight.editorActions + +import com.intellij.openapi.actionSystem.IdeActions +import com.intellij.testFramework.LightProjectDescriptor +import groovy.transform.CompileStatic +import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor +import org.jetbrains.plugins.groovy.LightGroovyTestCase + +@CompileStatic +class GroovyMoveLeftRightHandlerTest extends LightGroovyTestCase { + + final LightProjectDescriptor projectDescriptor = GroovyLightProjectDescriptor.GROOVY_LATEST + + private void doTest(String before, String after = null) { + fixture.with { + configureByText '_.groovy', before + performEditorAction(IdeActions.MOVE_ELEMENT_RIGHT) + if (after != null) { + checkResult after + performEditorAction(IdeActions.MOVE_ELEMENT_LEFT) + } + checkResult before + } + } + + void 'test annotation argument'() { + doTest '@MyAnno(a = "e", b = "f") def a', + '@MyAnno(b = "f", a = "e") def a' + doTest '@MyAnno(a = "e", b = "f") def a' + } + + void 'test annotation array initializer'() { + doTest '@MyAnno([1, 2, 3])', + '@MyAnno([2, 1, 3])' + doTest '@MyAnno(a = [1, 2, 3], b = 2)' + } + + void 'test argument list'() { + doTest 'def foo(def...a) {}; foo(1, 2, 3)', + 'def foo(def...a) {}; foo(1, 3, 2)' + doTest 'def foo(def...a) {}; foo(1, a: 2, 3)', + 'def foo(def...a) {}; foo(1, 3, a: 2)' + } + + void 'test enum definition'() { + doTest 'enum E {ONE, TWO, THREE}', + 'enum E {ONE, THREE, TWO}' + doTest 'enum E {ONE, TWO, THREE}' + } + + void 'test list or map'() { + doTest '[1, 2, 3]', + '[2, 1, 3]' + doTest '[a: 1, b: 2, c: 3]', + '[b: 2, a: 1, c: 3]' + doTest '[1, a: 2, 3]', + '[a: 2, 1, 3]' + } + + void 'test method modifier list'() { + doTest 'synchronized @Deprecated def foo() {}', + '@Deprecated synchronized def foo() {}' + doTest 'synchronized @Deprecated def foo() {}' + } + + void 'test class modifier list'() { + doTest 'public @Deprecated class A {}', + '@Deprecated public class A {}' + doTest 'public @Deprecated class A {}' + } + + void 'test parameter list'() { + doTest 'def foo(a, b = 2, c){}', + 'def foo(b = 2, a, c){}' + doTest 'def foo(a, b = 2, c){}' + } + + void 'test implements list'() { + doTest 'class A implements Foo, Bar, Baz {}', + 'class A implements Bar, Foo, Baz {}' + doTest 'class A implements Foo, Bar, Baz {}' + } + + void 'test extends list'() { + doTest 'class B extends Foo, Bar, Baz {}', + 'class B extends Bar, Foo, Baz {}' + doTest 'class B extends Foo, Bar, Baz {}' + } + + void 'test throws list'() { + doTest 'def foo() throws Foo, Bar, Baz {}', + 'def foo() throws Bar, Foo, Baz {}' + doTest 'def foo() throws Foo, Bar, Baz {}' + } + + void 'test type parameter list'() { + doTest 'class A<T, U, K> {}', + 'class AT, K> {}' + doTest 'class AK> {}' + } + + void 'test type argument list'() { + doTest 'new A<K,V>', 'new AK>' + doTest 'new AV>' + } + + void 'test variable declaration'() { + doTest 'def a = 1, b = 2, c', 'def a = 1, c, b = 2' + doTest 'def a = 1, b = 2, c' + } + + void 'test binary expression'() { + doTest '1 + 2 + 3' + doTest '1 + 2 + 3' + } +}