Made rename refactoring inplace for loop, catch and function literal parameters.

#KT-1296 fixed
This commit is contained in:
Evgeny Gerashchenko
2013-12-23 21:18:19 +04:00
parent 600bb49894
commit 90ad65bff8
18 changed files with 189 additions and 3 deletions
@@ -1006,9 +1006,15 @@ public class JetPsiUtil {
@Nullable
public static JetElement getEnclosingElementForLocalDeclaration(@Nullable JetNamedDeclaration declaration) {
if (declaration instanceof JetTypeParameter || declaration instanceof JetParameter) {
if (declaration instanceof JetTypeParameter) {
declaration = PsiTreeUtil.getParentOfType(declaration, JetNamedDeclaration.class);
}
else if (declaration instanceof JetParameter) {
PsiElement parent = declaration.getParent();
if (parent != null && parent.getParent() instanceof JetNamedFunction) {
declaration = (JetNamedFunction) parent.getParent();
}
}
//noinspection unchecked
JetElement container = PsiTreeUtil.getParentOfType(
@@ -20,6 +20,7 @@ import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.RefactoringActionHandler;
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureHandler;
@@ -28,7 +29,7 @@ import org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinSafeDeleteProcessor
public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
@Override
public boolean isSafeDeleteAvailable(PsiElement element) {
public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
return KotlinSafeDeleteProcessor.canDeleteElement(element);
}
@@ -38,7 +39,7 @@ public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
}
@Override
public boolean isInplaceRenameAvailable(PsiElement element, PsiElement context) {
public boolean isInplaceRenameAvailable(@NotNull PsiElement element, PsiElement context) {
if (element instanceof JetProperty) {
JetProperty property = (JetProperty) element;
if (property.isLocal()) return true;
@@ -47,6 +48,16 @@ public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
JetFunction function = (JetFunction) element;
if (function.isLocal()) return true;
}
else if (element instanceof JetParameter) {
PsiElement parent = element.getParent();
if (parent instanceof JetForExpression) {
return true;
}
if (parent instanceof JetParameterList) {
PsiElement grandparent = parent.getParent();
return grandparent instanceof JetCatchClause || grandparent instanceof JetFunctionLiteral;
}
}
return false;
}
@@ -0,0 +1,5 @@
fun f() {
for (<caret>i in 1..2) {
println(i + i)
}
}
@@ -0,0 +1,5 @@
fun f() {
for (<caret>j in 1..2) {
println(j + j)
}
}
@@ -0,0 +1,3 @@
fun f() {
val f: (Int) -> Int = { <caret>x -> x + x }
}
@@ -0,0 +1,3 @@
fun f() {
val f: (Int) -> Int = { <caret>y -> y + y }
}
@@ -0,0 +1,3 @@
fun f() {
val f = { (<caret>x: Int) -> x + x }
}
@@ -0,0 +1,3 @@
fun f() {
val f = { (<caret>y: Int) -> y + y }
}
@@ -0,0 +1,2 @@
fun f(<caret>a: String) {
}
@@ -0,0 +1,8 @@
fun <caret>foo(a: Int) {
}
fun f() {
foo(1)
foo(217)
}
@@ -0,0 +1,7 @@
fun f() {
fun <caret>foo(a: Int) {
}
foo(1)
foo(217)
}
@@ -0,0 +1,7 @@
fun f() {
fun <caret>bar(a: Int) {
}
bar(1)
bar(217)
}
@@ -0,0 +1,4 @@
fun f() {
val <caret>x = 5
println(x + x * x)
}
@@ -0,0 +1,4 @@
fun f() {
val <caret>y = 5
println(y + y * y)
}
@@ -0,0 +1,5 @@
val <caret>x = 5
fun f() {
println(x + x * x)
}
@@ -0,0 +1,7 @@
fun f() {
try {
}
catch (<caret>e: Exception) {
println(e)
}
}
@@ -0,0 +1,7 @@
fun f() {
try {
}
catch (<caret>e1: Exception) {
println(e1)
}
}
@@ -0,0 +1,96 @@
/*
* Copyright 2010-2013 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.jet.plugin.refactoring
import com.intellij.testFramework.LightCodeInsightTestCase
import com.intellij.codeInsight.TargetElementUtilBase
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
import com.intellij.testFramework.fixtures.CodeInsightTestUtil
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
import kotlin.test.*
import com.intellij.lang.java.JavaRefactoringSupportProvider
import com.intellij.testFramework.TestDataProvider
import com.intellij.testFramework.LightPlatformTestCase
import com.intellij.ide.DataManager
import org.jetbrains.jet.plugin.PluginTestCaseBase
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
public class InplaceRenameTest : LightCodeInsightTestCase() {
override fun isRunInWriteAction(): Boolean = false
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/refactoring/rename/inplace/"
public fun testLocalVal() {
doTestInplaceRename("y")
}
public fun testForLoop() {
doTestInplaceRename("j")
}
public fun testTryCatch() {
doTestInplaceRename("e1")
}
public fun testFunctionLiteral() {
doTestInplaceRename("y")
}
public fun testFunctionLiteralParenthesis() {
doTestInplaceRename("y")
}
public fun testLocalFunction() {
doTestInplaceRename("bar")
}
public fun testFunctionParameterNotInplace() {
doTestInplaceRename(null)
}
public fun testGlobalFunctionNotInplace() {
doTestInplaceRename(null)
}
public fun testTopLevelValNotInplace() {
doTestInplaceRename(null)
}
private fun doTestInplaceRename(newName: String?) {
configureByFile(getTestName(false) + ".kt")
val element = TargetElementUtilBase.findTargetElement(
LightPlatformCodeInsightTestCase.myEditor,
TargetElementUtilBase.ELEMENT_NAME_ACCEPTED or TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED
)
assertNotNull(element)
val dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PSI_ELEMENT.getName(), element!!,
LightPlatformCodeInsightTestCase.getCurrentEditorDataContext())
val handler = VariableInplaceRenameHandler()
if (newName == null) {
assertFalse(handler.isRenaming(dataContext), "In-place rename is allowed for " + element)
}
else {
assertTrue(handler.isRenaming(dataContext), "In-place rename not allowed for " + element)
CodeInsightTestUtil.doInlineRename(handler, newName, LightPlatformCodeInsightTestCase.getEditor(), element)
checkResultByFile(getTestName(false) + ".kt.after")
}
}
}