Rename: Check redeclaration for local variables

Also add tests for other local declarations

 #KT-13255 Fixed
This commit is contained in:
Alexey Sedunov
2018-02-26 19:02:13 +03:00
parent 4609b2ae37
commit 6c17bbe42c
6 changed files with 43 additions and 11 deletions
@@ -18,9 +18,6 @@ open class KotlinVariableInplaceRenameHandler : VariableInplaceRenameHandler() {
fun isInplaceRenameAvailable(element: PsiElement): Boolean {
when (element) {
is KtTypeParameter -> return true
is KtProperty -> {
if (element.isLocal) return true
}
is KtDestructuringDeclarationEntry -> return true
is KtParameter -> {
val parent = element.parent
@@ -105,7 +105,7 @@ internal fun checkRedeclarations(
fun MemberScope.findSiblingsByName(): List<DeclarationDescriptor> {
val descriptorKindFilter = when (descriptor) {
is ClassifierDescriptor -> DescriptorKindFilter.CLASSIFIERS
is PropertyDescriptor -> DescriptorKindFilter.VARIABLES
is VariableDescriptor -> DescriptorKindFilter.VARIABLES
is FunctionDescriptor -> DescriptorKindFilter.FUNCTIONS
else -> return emptyList()
}
@@ -150,7 +150,7 @@ internal fun checkRedeclarations(
if (it.name != newName) return@mapNotNull null
val isAccepted = when (descriptor) {
is ClassDescriptor -> it is KtClassOrObject
is PropertyDescriptor -> it is KtProperty
is VariableDescriptor -> it is KtProperty
is FunctionDescriptor -> it is KtNamedFunction
else -> false
}
@@ -0,0 +1,5 @@
// SHOULD_FAIL_WITH: Class 'LocalClassB' is already declared in function 'containNames'
fun containNames() {
class <caret>LocalClassA {}
class LocalClassB {}
}
@@ -0,0 +1,5 @@
// SHOULD_FAIL_WITH: Function 'localFunB' is already declared in function 'containNames'
fun containNames() {
fun <caret>localFunA() = 11
fun localFunB() = 12
}
@@ -0,0 +1,5 @@
// SHOULD_FAIL_WITH: Variable 'localValB' is already declared in function 'containNames'
fun containNames() {
val <caret>localValA = 11
val localValB = 12
}
@@ -11,15 +11,18 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.refactoring.BaseRefactoringProcessor
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
import com.intellij.testFramework.fixtures.CodeInsightTestUtil
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.refactoring.rename.KotlinMemberInplaceRenameHandler
import org.jetbrains.kotlin.idea.refactoring.rename.KotlinVariableInplaceRenameHandler
import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinImplicitLambdaParameter
import org.jetbrains.kotlin.idea.refactoring.rename.findElementForRename
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import kotlin.test.assertFalse
import kotlin.test.assertTrue
@@ -28,7 +31,7 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/refactoring/rename/inplace/"
fun testLocalVal() {
doTestInplaceRename("y")
doTestMemberInplaceRename("y")
}
fun testForLoop() {
@@ -80,7 +83,7 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
}
fun testLocalVarShadowingMemberProperty() {
doTestInplaceRename("name1")
doTestMemberInplaceRename("name1")
}
fun testNoReformat() {
@@ -144,7 +147,7 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
}
fun testQuotedLocalVar() {
doTestInplaceRename("x")
doTestMemberInplaceRename("x")
}
fun testQuotedParameter() {
@@ -155,6 +158,18 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
doTestMemberInplaceRename("")
}
fun testLocalVarRedeclaration() {
doTestMemberInplaceRename("localValB")
}
fun testLocalFunRedeclaration() {
doTestMemberInplaceRename("localFunB")
}
fun testLocalClassRedeclaration() {
doTestMemberInplaceRename("LocalClassB")
}
private fun doTestImplicitLambdaParameter(newName: String) {
configureByFile(getTestName(false) + ".kt")
@@ -225,9 +240,14 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
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")
try {
assertTrue(handler.isRenaming(dataContext), "In-place rename not allowed for " + element)
CodeInsightTestUtil.doInlineRename(handler, newName, LightPlatformCodeInsightTestCase.getEditor(), element)
checkResultByFile(getTestName(false) + ".kt.after")
} catch (e: BaseRefactoringProcessor.ConflictsInTestsException) {
val expectedMessage = InTextDirectivesUtils.findStringWithPrefixes(myFile.text, "// SHOULD_FAIL_WITH: ")
TestCase.assertEquals(expectedMessage, e.messages.joinToString())
}
}
}
}