[groovy] support 'Move element left/right' action (IDEA-158612)

This commit is contained in:
Daniil Ovchinnikov
2016-11-24 21:09:48 +03:00
parent 9572b5c756
commit b7eaaf1cec
3 changed files with 184 additions and 0 deletions
+2
View File
@@ -360,6 +360,8 @@
<nameSuggestionProvider implementation="org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionProvider"/>
<statementUpDownMover implementation="org.jetbrains.plugins.groovy.editor.actions.GroovyStatementMover"/>
<moveLeftRightHandler language="Groovy"
implementationClass="org.jetbrains.plugins.groovy.codeInsight.editorActions.GroovyMoveLeftRightHandler"/>
<joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrVariableJoinLinesHandler"/>
<joinLinesHandler implementation="org.jetbrains.plugins.groovy.editor.actions.joinLines.GrJoinBlockStatementHandler"/>
@@ -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<out PsiElement> = 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
}
}
@@ -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 = <caret>"e", b = "f") def a',
'@MyAnno(b = "f", a = <caret>"e") def a'
doTest '@MyAnno(a = "e", <caret>b = "f") def a'
}
void 'test annotation array initializer'() {
doTest '@MyAnno([<caret>1, 2, 3])',
'@MyAnno([2, <caret>1, 3])'
doTest '@MyAnno(a = [1, 2, <caret>3], b = 2)'
}
void 'test argument list'() {
doTest 'def foo(def...a) {}; foo(1, <caret>2, 3)',
'def foo(def...a) {}; foo(1, 3, <caret>2)'
doTest 'def foo(def...a) {}; foo(1, <caret>a: 2, 3)',
'def foo(def...a) {}; foo(1, 3, <caret>a: 2)'
}
void 'test enum definition'() {
doTest 'enum E {ONE, <caret>TWO, THREE}',
'enum E {ONE, THREE, <caret>TWO}'
doTest 'enum E {ONE, TWO, <caret>THREE}'
}
void 'test list or map'() {
doTest '[<caret>1, 2, 3]',
'[2, <caret>1, 3]'
doTest '[<caret>a: 1, b: 2, c: 3]',
'[b: 2, <caret>a: 1, c: 3]'
doTest '[<caret>1, a: 2, 3]',
'[a: 2, <caret>1, 3]'
}
void 'test method modifier list'() {
doTest '<caret>synchronized @Deprecated def foo() {}',
'@Deprecated <caret>synchronized def foo() {}'
doTest 'synchronized @Deprecated <caret>def foo() {}'
}
void 'test class modifier list'() {
doTest '<caret>public @Deprecated class A {}',
'@Deprecated <caret>public class A {}'
doTest 'public <caret>@Deprecated class A {}'
}
void 'test parameter list'() {
doTest 'def foo(<caret>a, b = 2, c){}',
'def foo(b = 2, <caret>a, c){}'
doTest 'def foo(a, b = 2, <caret>c){}'
}
void 'test implements list'() {
doTest 'class A implements <caret>Foo, Bar, Baz {}',
'class A implements Bar, <caret>Foo, Baz {}'
doTest 'class A implements Foo, Bar, <caret>Baz {}'
}
void 'test extends list'() {
doTest 'class B extends <caret>Foo, Bar, Baz {}',
'class B extends Bar, <caret>Foo, Baz {}'
doTest 'class B extends Foo, Bar, <caret>Baz {}'
}
void 'test throws list'() {
doTest 'def foo() throws <caret>Foo, Bar, Baz {}',
'def foo() throws Bar, <caret>Foo, Baz {}'
doTest 'def foo() throws Foo, Bar, <caret>Baz {}'
}
void 'test type parameter list'() {
doTest 'class A<<caret>T, U, K> {}',
'class A<U, <caret>T, K> {}'
doTest 'class A<T, U, <caret>K> {}'
}
void 'test type argument list'() {
doTest 'new A<<caret>K,V>', 'new A<V,<caret>K>'
doTest 'new A<K,<caret>V>'
}
void 'test variable declaration'() {
doTest 'def a = 1, <caret>b = 2, c', 'def a = 1, c, <caret>b = 2'
doTest 'def a = 1, b = 2, <caret>c'
}
void 'test binary expression'() {
doTest '<caret>1 + 2 + 3'
doTest '1 + <caret>2 + 3'
}
}