[kotlin] forbid synthetic methods rename from java

^KTIJ-26822 fixed

GitOrigin-RevId: cf7672f2e8bf3a6be76117f2b6d7af15b6087207
This commit is contained in:
Anna Kozlova
2024-10-14 12:20:48 +02:00
committed by intellij-monorepo-bot
parent 7da94f7f29
commit ab9d93e60c
19 changed files with 136 additions and 27 deletions

View File

@@ -210,11 +210,26 @@ public class RenameTestGenerated extends AbstractRenameTest {
runTest("testData/refactoring/rename/dataClassComponentN/dataClassComponentN.test");
}
@TestMetadata("dataClassCopyFromJava/dataClassCopy.test")
public void testDataClassCopyFromJava_DataClassCopy() throws Exception {
runTest("testData/refactoring/rename/dataClassCopyFromJava/dataClassCopy.test");
}
@TestMetadata("dataClassCopy/dataClassCopy.test")
public void testDataClassCopy_DataClassCopy() throws Exception {
runTest("testData/refactoring/rename/dataClassCopy/dataClassCopy.test");
}
@TestMetadata("enumGetEntriesFromJava/enumValueOf.test")
public void testEnumGetEntriesFromJava_EnumValueOf() throws Exception {
runTest("testData/refactoring/rename/enumGetEntriesFromJava/enumValueOf.test");
}
@TestMetadata("enumValueOfFromJava/enumValueOf.test")
public void testEnumValueOfFromJava_EnumValueOf() throws Exception {
runTest("testData/refactoring/rename/enumValueOfFromJava/enumValueOf.test");
}
@TestMetadata("enumValueOf/enumValueOf.test")
public void testEnumValueOf_EnumValueOf() throws Exception {
runTest("testData/refactoring/rename/enumValueOf/enumValueOf.test");

View File

@@ -0,0 +1,5 @@
class JavaClass {
void test() {
new XYZ(1, 2, 3)./*rename*/copy(10, 2, 3)
}
}

View File

@@ -0,0 +1 @@
data class XYZ(val x: Int, val y: Int, val z: Int)

View File

@@ -0,0 +1,5 @@
class JavaClass {
void test() {
new XYZ(1, 2, 3)./*rename*/copy(10, 2, 3)
}
}

View File

@@ -0,0 +1 @@
data class XYZ(val x: Int, val y: Int, val z: Int)

View File

@@ -0,0 +1,8 @@
{
"type": "AUTO_DETECT",
"mainFile": "JavaClass.java",
"newName": "copyNew",
"withRuntime": "true",
"hint": "Rename is not applicable to synthetic declaration",
"enabledInK2": true
}

View File

@@ -0,0 +1,5 @@
class JavaClass {
{
Foo./*rename*/getEntries();
}
}

View File

@@ -0,0 +1 @@
enum class Foo{BAR, BAZ}

View File

@@ -0,0 +1,5 @@
class JavaClass {
{
Foo./*rename*/getEntries();
}
}

View File

@@ -0,0 +1 @@
enum class Foo{BAR, BAZ}

View File

@@ -0,0 +1,8 @@
{
"type": "AUTO_DETECT",
"mainFile": "JavaClass.java",
"newName": "getEntries1",
"withRuntime": "true",
"hint": "Rename is not applicable to synthetic declaration",
"enabledInK2": true
}

View File

@@ -0,0 +1,5 @@
class JavaClass {
{
Foo./*rename*/valueOf("BAR");
}
}

View File

@@ -0,0 +1 @@
enum class Foo{BAR, BAZ}

View File

@@ -0,0 +1,5 @@
class JavaClass {
{
Foo./*rename*/valueOf("BAR");
}
}

View File

@@ -0,0 +1 @@
enum class Foo{BAR, BAZ}

View File

@@ -0,0 +1,8 @@
{
"type": "AUTO_DETECT",
"mainFile": "JavaClass.java",
"newName": "valueOfNew",
"withRuntime": "true",
"hint": "Rename is not applicable to synthetic declaration",
"enabledInK2": true
}

View File

@@ -21,37 +21,40 @@ import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
internal abstract class AbstractForbidRenamingSymbolByReferenceHandler : RenameHandler {
override fun isAvailableOnDataContext(dataContext: DataContext): Boolean {
val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return false
val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return false
val refExpression = file.findElementForRename<KtSimpleNameExpression>(editor.caretModel.offset) ?: return false
@OptIn(KaAllowAnalysisOnEdt::class)
allowAnalysisOnEdt {
analyze(refExpression) {
val target = refExpression.mainReference.resolveToSymbol() ?: return false
return shouldForbidRenaming(target)
}
override fun isAvailableOnDataContext(dataContext: DataContext): Boolean {
val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return false
val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return false
if (shouldForbidRenamingFromJava(file, editor)) return true
val refExpression = file.findElementForRename<KtSimpleNameExpression>(editor.caretModel.offset) ?: return false
@OptIn(KaAllowAnalysisOnEdt::class)
allowAnalysisOnEdt {
analyze(refExpression) {
val target = refExpression.mainReference.resolveToSymbol() ?: return false
return shouldForbidRenaming(target)
}
}
}
}
context(KaSession)
abstract fun shouldForbidRenaming(symbol: KaSymbol): Boolean
open fun shouldForbidRenamingFromJava(file: PsiFile, editor: Editor): Boolean = false
abstract fun getErrorMessage(): @DialogMessage String
context(KaSession)
abstract fun shouldForbidRenaming(symbol: KaSymbol): Boolean
override fun isRenaming(dataContext: DataContext) = isAvailableOnDataContext(dataContext)
abstract fun getErrorMessage(): @DialogMessage String
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) {
CommonRefactoringUtil.showErrorHint(
project,
editor,
getErrorMessage(),
RefactoringBundle.message("rename.title"),
null
)
}
override fun isRenaming(dataContext: DataContext) = isAvailableOnDataContext(dataContext)
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
// Do nothing: this method is not called from editor
}
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) {
CommonRefactoringUtil.showErrorHint(
project,
editor,
getErrorMessage(),
RefactoringBundle.message("rename.title"),
null
)
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
// Do nothing: this method is not called from editor
}
}

View File

@@ -1,14 +1,30 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.refactoring.rename.handlers
import com.intellij.codeInsight.TargetElementUtil
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.NlsContexts.DialogMessage
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiJavaFile
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.symbols.KaConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbolOrigin
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.psi.KtCallableDeclaration
internal class RenameSyntheticDeclarationByReferenceHandler : AbstractForbidRenamingSymbolByReferenceHandler() {
override fun shouldForbidRenamingFromJava(file: PsiFile, editor: Editor): Boolean {
if (file is PsiJavaFile) {
val targetElement = TargetElementUtil.findTargetElement(editor, TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED) as? KtLightMethod
?: return false
return targetElement.kotlinOrigin !is KtCallableDeclaration
}
return false
}
context(KaSession)
override fun shouldForbidRenaming(symbol: KaSymbol): Boolean {
return symbol.origin == KaSymbolOrigin.SOURCE_MEMBER_GENERATED && !(symbol is KaConstructorSymbol && symbol.isPrimary)

View File

@@ -210,11 +210,26 @@ public class FirRenameTestGenerated extends AbstractFirRenameTest {
runTest("../../idea/tests/testData/refactoring/rename/dataClassComponentN/dataClassComponentN.test");
}
@TestMetadata("dataClassCopyFromJava/dataClassCopy.test")
public void testDataClassCopyFromJava_DataClassCopy() throws Exception {
runTest("../../idea/tests/testData/refactoring/rename/dataClassCopyFromJava/dataClassCopy.test");
}
@TestMetadata("dataClassCopy/dataClassCopy.test")
public void testDataClassCopy_DataClassCopy() throws Exception {
runTest("../../idea/tests/testData/refactoring/rename/dataClassCopy/dataClassCopy.test");
}
@TestMetadata("enumGetEntriesFromJava/enumValueOf.test")
public void testEnumGetEntriesFromJava_EnumValueOf() throws Exception {
runTest("../../idea/tests/testData/refactoring/rename/enumGetEntriesFromJava/enumValueOf.test");
}
@TestMetadata("enumValueOfFromJava/enumValueOf.test")
public void testEnumValueOfFromJava_EnumValueOf() throws Exception {
runTest("../../idea/tests/testData/refactoring/rename/enumValueOfFromJava/enumValueOf.test");
}
@TestMetadata("enumValueOf/enumValueOf.test")
public void testEnumValueOf_EnumValueOf() throws Exception {
runTest("../../idea/tests/testData/refactoring/rename/enumValueOf/enumValueOf.test");