Rename: Fix processing of overriding methods with mangled names
#KT-24460 Fixed
This commit is contained in:
@@ -1676,13 +1676,21 @@ public class KotlinTypeMapper {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String internalNameWithoutModuleSuffix(@NotNull String name) {
|
||||
public static String demangleInternalName(@NotNull String name) {
|
||||
int indexOfDollar = name.indexOf('$');
|
||||
if (indexOfDollar == -1) {
|
||||
return null;
|
||||
}
|
||||
return indexOfDollar >= 0 ? name.substring(0, indexOfDollar) : null;
|
||||
}
|
||||
|
||||
return name.substring(0, indexOfDollar) + '$';
|
||||
@Nullable
|
||||
public static String getModuleNameSuffix(@NotNull String name) {
|
||||
int indexOfDollar = name.indexOf('$');
|
||||
return indexOfDollar >=0 ? name.substring(indexOfDollar + 1) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String internalNameWithoutModuleSuffix(@NotNull String name) {
|
||||
String demangledName = demangleInternalName(name);
|
||||
return demangledName != null ? demangledName + '$' : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +44,6 @@ interface KtLightMethod : PsiAnnotationMethod, KtLightMember<PsiMethod> {
|
||||
val isDelegated: Boolean
|
||||
get() = lightMemberOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION
|
||||
|| lightMemberOrigin?.originKind == JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL
|
||||
|
||||
val isMangled: Boolean
|
||||
}
|
||||
+10
-1
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.asJava.classes.cannotModify
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.asJava.propertyNameByAccessor
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -84,9 +85,17 @@ class KtLightMethodImpl private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override val isMangled: Boolean
|
||||
get() {
|
||||
val demangledName = KotlinTypeMapper.InternalNameMapper.demangleInternalName(name) ?: return false
|
||||
val originalName = propertyNameByAccessor(demangledName, this) ?: demangledName
|
||||
return originalName == kotlinOrigin?.name
|
||||
}
|
||||
|
||||
override fun setName(name: String): PsiElement? {
|
||||
val jvmNameAnnotation = modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString())
|
||||
val newNameForOrigin = propertyNameByAccessor(name, this) ?: name
|
||||
val demangledName = (if (isMangled) KotlinTypeMapper.InternalNameMapper.demangleInternalName(name) else null) ?: name
|
||||
val newNameForOrigin = propertyNameByAccessor(demangledName, this) ?: demangledName
|
||||
if (newNameForOrigin == kotlinOrigin?.name) {
|
||||
jvmNameAnnotation?.delete()
|
||||
return this
|
||||
|
||||
+10
-2
@@ -227,6 +227,9 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
||||
}
|
||||
else if (declaration is KtFunction) {
|
||||
processStaticsFromCompanionObject(declaration)
|
||||
if (element.isMangled) {
|
||||
searchNamedElement(declaration) { it.restrictToKotlinSources() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,9 +300,14 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
||||
return allMethods.filter { it is KtLightMethod && it.kotlinOrigin == declaration }
|
||||
}
|
||||
|
||||
private fun searchNamedElement(element: PsiNamedElement?, name: String? = element?.name) {
|
||||
private fun searchNamedElement(
|
||||
element: PsiNamedElement?,
|
||||
name: String? = element?.name,
|
||||
modifyScope: ((SearchScope) -> SearchScope)? = null
|
||||
) {
|
||||
if (name != null && element != null) {
|
||||
val scope = queryParameters.effectiveSearchScope(element)
|
||||
val baseScope = queryParameters.effectiveSearchScope(element)
|
||||
val scope = if (modifyScope != null) modifyScope(baseScope) else baseScope
|
||||
val context = UsageSearchContext.IN_CODE + UsageSearchContext.IN_FOREIGN_LANGUAGES + UsageSearchContext.IN_COMMENTS
|
||||
val resultProcessor = KotlinRequestResultProcessor(element,
|
||||
queryParameters.elementToSearch.namedUnwrappedElement ?: element,
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ class RenameKotlinClassifierProcessor : RenameKotlinPsiProcessor() {
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun renameElement(element: PsiElement, newName: String, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) {
|
||||
override fun renameElement(element: PsiElement, newName: String, usages: Array<UsageInfo>, listener: RefactoringElementListener?) {
|
||||
val simpleUsages = ArrayList<UsageInfo>(usages.size)
|
||||
val ambiguousImportUsages = com.intellij.util.SmartList<UsageInfo>()
|
||||
for (usage in usages) {
|
||||
|
||||
+11
-5
@@ -35,6 +35,8 @@ import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.InternalNameMapper.demangleInternalName
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.InternalNameMapper.getModuleNameSuffix
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.refactoring.Pass
|
||||
@@ -181,6 +183,8 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
||||
override fun prepareRenaming(element: PsiElement, newName: String, allRenames: MutableMap<PsiElement, String>, scope: SearchScope) {
|
||||
super.prepareRenaming(element, newName, allRenames, scope)
|
||||
|
||||
val originalName = (element.unwrapped as? KtNamedFunction)?.name ?: ""
|
||||
|
||||
if (element is KtLightMethod && getJvmName(element) == null) {
|
||||
(element.kotlinOrigin as? KtNamedFunction)?.let { allRenames[it] = newName }
|
||||
}
|
||||
@@ -190,22 +194,22 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
||||
for (declaration in ((element as? FunctionWithSupersWrapper)?.supers ?: listOf(element))) {
|
||||
val psiMethod = wrapPsiMethod(declaration) ?: continue
|
||||
allRenames[declaration] = newName
|
||||
val baseName = psiMethod.name
|
||||
val newBaseName = if (demangleInternalName(baseName) == originalName) "$newName$${getModuleNameSuffix(baseName)}" else newName
|
||||
if (psiMethod.containingClass != null) {
|
||||
psiMethod.forEachOverridingMethod { it ->
|
||||
psiMethod.forEachOverridingMethod(scope) { it ->
|
||||
val overrider = (it as? PsiMirrorElement)?.prototype as? PsiMethod ?: it
|
||||
|
||||
if (overrider is SyntheticElement) return@forEachOverridingMethod true
|
||||
|
||||
val overriderName = overrider.name
|
||||
val baseName = psiMethod.name
|
||||
val newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, baseName, newName)
|
||||
val newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, baseName, newBaseName)
|
||||
if (newOverriderName != null) {
|
||||
RenameProcessor.assertNonCompileElement(overrider)
|
||||
allRenames.put(overrider, newOverriderName)
|
||||
}
|
||||
return@forEachOverridingMethod true
|
||||
}
|
||||
javaMethodProcessorInstance.prepareRenaming(psiMethod, newName, allRenames, scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,7 +227,9 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
|
||||
ambiguousImportUsages += usage
|
||||
}
|
||||
else {
|
||||
simpleUsages += usage
|
||||
if (!renameUsageIfPossible(usage, element, newName)) {
|
||||
simpleUsages += usage
|
||||
}
|
||||
}
|
||||
}
|
||||
element.ambiguousImportUsages = ambiguousImportUsages
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ class RenameKotlinParameterProcessor : RenameKotlinPsiProcessor() {
|
||||
result += collisions
|
||||
}
|
||||
|
||||
override fun renameElement(element: PsiElement, newName: String, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) {
|
||||
override fun renameElement(element: PsiElement, newName: String, usages: Array<UsageInfo>, listener: RefactoringElementListener?) {
|
||||
super.renameElement(element, newName, usages, listener)
|
||||
|
||||
usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() }
|
||||
|
||||
+19
-6
@@ -36,6 +36,9 @@ import org.jetbrains.kotlin.asJava.*
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.InternalNameMapper.demangleInternalName
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.InternalNameMapper.getModuleNameSuffix
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.InternalNameMapper.mangleInternalName
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
@@ -323,16 +326,21 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
|
||||
}
|
||||
|
||||
for (propertyMethod in propertyMethods) {
|
||||
if (element is KtDeclaration && newPropertyName != null) {
|
||||
val mangledPropertyName = if (propertyMethod is KtLightMethod && propertyMethod.isMangled) {
|
||||
val suffix = getModuleNameSuffix(propertyMethod.name)
|
||||
if (suffix != null && newPropertyName != null) mangleInternalName(newPropertyName, suffix) else null
|
||||
} else null
|
||||
val adjustedPropertyName = mangledPropertyName ?: newPropertyName
|
||||
if (element is KtDeclaration && adjustedPropertyName != null) {
|
||||
val wrapper = PropertyMethodWrapper(propertyMethod)
|
||||
when {
|
||||
JvmAbi.isGetterName(propertyMethod.name) && getterJvmName == null ->
|
||||
allRenames[wrapper] = JvmAbi.getterName(newPropertyName)
|
||||
allRenames[wrapper] = JvmAbi.getterName(adjustedPropertyName)
|
||||
JvmAbi.isSetterName(propertyMethod.name) && setterJvmName == null ->
|
||||
allRenames[wrapper] = JvmAbi.setterName(newPropertyName)
|
||||
allRenames[wrapper] = JvmAbi.setterName(adjustedPropertyName)
|
||||
}
|
||||
}
|
||||
addRenameElements(propertyMethod, (element as PsiNamedElement).name, newPropertyName, allRenames, scope)
|
||||
addRenameElements(propertyMethod, (element as PsiNamedElement).name, adjustedPropertyName, allRenames, scope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +397,10 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
|
||||
val refKindUsages = adjustedUsages.groupBy { usage: UsageInfo ->
|
||||
val refElement = usage.reference?.resolve()
|
||||
if (refElement is PsiMethod) {
|
||||
when (refElement.name) {
|
||||
val refElementName = refElement.name
|
||||
val refElementNameToCheck =
|
||||
(if (usage is MangledJavaRefUsageInfo) demangleInternalName(refElementName) else null) ?: refElementName
|
||||
when (refElementNameToCheck) {
|
||||
oldGetterName -> UsageKind.GETTER_USAGE
|
||||
oldSetterName -> UsageKind.SETTER_USAGE
|
||||
else -> UsageKind.SIMPLE_PROPERTY_USAGE
|
||||
@@ -441,7 +452,9 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
val newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, oldName, newName)
|
||||
val demangledName = if (newName != null && overrider is KtLightMethod && overrider.isMangled) demangleInternalName(newName) else null
|
||||
val adjustedName = demangledName ?: newName
|
||||
val newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, oldName, adjustedName)
|
||||
if (newOverriderName != null) {
|
||||
allRenames[overriderElement] = newOverriderName
|
||||
}
|
||||
|
||||
@@ -24,10 +24,15 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.psi.util.PsiUtilCore
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener
|
||||
import com.intellij.refactoring.rename.RenamePsiElementProcessor
|
||||
import com.intellij.refactoring.rename.RenameUtil
|
||||
import com.intellij.refactoring.util.MoveRenameUsageInfo
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
||||
import org.jetbrains.kotlin.idea.search.projectScope
|
||||
@@ -40,15 +45,43 @@ import org.jetbrains.kotlin.psi.psiUtil.isIdentifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import java.util.ArrayList
|
||||
import kotlin.collections.Collection
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.collections.List
|
||||
import kotlin.collections.MutableMap
|
||||
import kotlin.collections.flatMapTo
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.isEmpty
|
||||
import kotlin.collections.mapNotNullTo
|
||||
import kotlin.collections.none
|
||||
import kotlin.collections.plusAssign
|
||||
import kotlin.collections.set
|
||||
import kotlin.collections.toMutableList
|
||||
import kotlin.collections.toTypedArray
|
||||
|
||||
abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() {
|
||||
class MangledJavaRefUsageInfo(
|
||||
val manglingSuffix: String,
|
||||
element: PsiElement,
|
||||
ref: PsiReference,
|
||||
referenceElement: PsiElement
|
||||
) : MoveRenameUsageInfo(
|
||||
referenceElement,
|
||||
ref,
|
||||
ref.getRangeInElement().getStartOffset(),
|
||||
ref.getRangeInElement().getEndOffset(),
|
||||
element,
|
||||
false
|
||||
)
|
||||
|
||||
override fun canProcessElement(element: PsiElement): Boolean = element is KtNamedDeclaration
|
||||
|
||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
||||
val searchParameters = KotlinReferencesSearchParameters(
|
||||
element,
|
||||
element.project.projectScope(),
|
||||
kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false)
|
||||
element,
|
||||
element.project.projectScope(),
|
||||
kotlinOptions = KotlinReferencesSearchOptions(searchForComponentConventions = false)
|
||||
)
|
||||
val references = ReferencesSearch.search(searchParameters).toMutableList()
|
||||
if (element is KtNamedFunction
|
||||
@@ -59,6 +92,23 @@ abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() {
|
||||
return references
|
||||
}
|
||||
|
||||
override fun createUsageInfo(element: PsiElement, ref: PsiReference, referenceElement: PsiElement): UsageInfo {
|
||||
if (ref !is KtReference) {
|
||||
val targetElement = ref.resolve()
|
||||
if (targetElement is KtLightMethod && targetElement.isMangled) {
|
||||
KotlinTypeMapper.InternalNameMapper.getModuleNameSuffix(targetElement.name)?.let {
|
||||
return MangledJavaRefUsageInfo(
|
||||
it,
|
||||
element,
|
||||
ref,
|
||||
referenceElement
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.createUsageInfo(element, ref, referenceElement)
|
||||
}
|
||||
|
||||
override fun getElementToSearchInStringsAndComments(element: PsiElement): PsiElement? {
|
||||
val unwrapped = element?.unwrapped ?: return null
|
||||
if ((unwrapped is KtDeclaration) && KtPsiUtil.isLocal(unwrapped as KtDeclaration)) return null
|
||||
@@ -101,12 +151,44 @@ abstract class RenameKotlinPsiProcessor : RenamePsiElementProcessor() {
|
||||
&& ref.multiResolve(false).mapNotNullTo(HashSet()) { it.element?.unwrapped }.size > 1
|
||||
}
|
||||
|
||||
protected fun renameUsageIfPossible(usage: UsageInfo, element: PsiElement, newName: String): Boolean {
|
||||
var chosenName: String? = null
|
||||
if (usage is MangledJavaRefUsageInfo) {
|
||||
chosenName = KotlinTypeMapper.InternalNameMapper.mangleInternalName(newName, usage.manglingSuffix)
|
||||
} else {
|
||||
val reference = usage.reference
|
||||
if (reference is KtReference) {
|
||||
chosenName = (if (element is KtLightMethod && element.isMangled) KotlinTypeMapper.InternalNameMapper.demangleInternalName(newName) else null) ?: newName
|
||||
}
|
||||
}
|
||||
if (chosenName == null) return false
|
||||
usage.reference?.handleElementRename(chosenName)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun renameElement(
|
||||
element: PsiElement,
|
||||
newName: String,
|
||||
usages: Array<UsageInfo>,
|
||||
listener: RefactoringElementListener?
|
||||
) {
|
||||
val simpleUsages = ArrayList<UsageInfo>(usages.size)
|
||||
for (usage in usages) {
|
||||
if (renameUsageIfPossible(usage, element, newName)) continue
|
||||
simpleUsages += usage
|
||||
}
|
||||
|
||||
RenameUtil.doRenameGenericNamedElement(element, newName, simpleUsages.toTypedArray(), listener)
|
||||
}
|
||||
|
||||
override fun getPostRenameCallback(element: PsiElement, newName: String, elementListener: RefactoringElementListener): Runnable? {
|
||||
return Runnable {
|
||||
element.ambiguousImportUsages?.forEach {
|
||||
val ref = it.reference as? PsiPolyVariantReference ?: return@forEach
|
||||
if (ref.multiResolve(false).isEmpty()) {
|
||||
ref.handleElementRename(newName)
|
||||
if (!renameUsageIfPossible(it, element, newName)) {
|
||||
ref.handleElementRename(newName)
|
||||
}
|
||||
}
|
||||
else {
|
||||
ref.element?.getStrictParentOfType<KtImportDirective>()?.let { importDirective ->
|
||||
|
||||
+23
@@ -24,6 +24,7 @@ import com.intellij.psi.search.UsageSearchContext
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||
import com.intellij.psi.util.MethodSignatureUtil
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.compatibility.ExecutorProcessor
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
@@ -31,8 +32,10 @@ import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
|
||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||
import org.jetbrains.kotlin.idea.util.runReadActionInSmartMode
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.getPropertyNamesCandidatesByAccessorName
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.InternalNameMapper.demangleInternalName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
@@ -47,6 +50,26 @@ class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() {
|
||||
return
|
||||
}
|
||||
|
||||
if (method is KtLightMethod) {
|
||||
method.kotlinOrigin?.let { ktElement ->
|
||||
val (mayBeMangled, name) = p.project.runReadActionInSmartMode {
|
||||
ktElement.hasModifier(KtTokens.PRIVATE_KEYWORD) || ktElement.hasModifier(KtTokens.INTERNAL_KEYWORD)
|
||||
} to method.name
|
||||
if (mayBeMangled && name != null) {
|
||||
val demangledName = demangleInternalName(name)
|
||||
if (demangledName != null) {
|
||||
val wrappedMethod = object : KtLightMethod by method {
|
||||
override fun getName(): String = demangledName
|
||||
}
|
||||
processQuery(
|
||||
MethodReferencesSearch.SearchParameters(wrappedMethod, p.scopeDeterminedByUser, p.isStrictSignatureSearch, p.optimizer),
|
||||
consumer
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val searchScope = p.project.runReadActionInSmartMode {
|
||||
p.effectiveSearchScope
|
||||
.intersectWith(method.useScope)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class J extends X.Y {
|
||||
@Override
|
||||
public int newOverridableMethod$production_sources_for_module_light_idea_test_case(int x) {
|
||||
return super.newOverridableMethod$production_sources_for_module_light_idea_test_case(x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
sealed class X {
|
||||
internal abstract fun newOverridableMethod(x: Int): Int
|
||||
|
||||
abstract class Y : X() {
|
||||
override fun newOverridableMethod(x: Int): Int = 1
|
||||
}
|
||||
|
||||
class Z : Y() {
|
||||
override fun newOverridableMethod(x: Int): Int =
|
||||
if (x > 0) x
|
||||
else super.newOverridableMethod(x)
|
||||
}
|
||||
}
|
||||
|
||||
fun get() : X? {
|
||||
return X.Z()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
get()?.newOverridableMethod(2)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class J extends X.Y {
|
||||
@Override
|
||||
public int overridableMethod$production_sources_for_module_light_idea_test_case(int x) {
|
||||
return super.overridableMethod$production_sources_for_module_light_idea_test_case(x);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
sealed class X {
|
||||
internal abstract fun /*rename*/overridableMethod(x: Int): Int
|
||||
|
||||
abstract class Y : X() {
|
||||
override fun overridableMethod(x: Int): Int = 1
|
||||
}
|
||||
|
||||
class Z : Y() {
|
||||
override fun overridableMethod(x: Int): Int =
|
||||
if (x > 0) x
|
||||
else super.overridableMethod(x)
|
||||
}
|
||||
}
|
||||
|
||||
fun get() : X? {
|
||||
return X.Z()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
get()?.overridableMethod(2)
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"type": "MARKED_ELEMENT",
|
||||
"mainFile": "test.kt",
|
||||
"newName": "newOverridableMethod"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class J extends X.Y {
|
||||
@Override
|
||||
public int getNewOverridableVar$production_sources_for_module_light_idea_test_case() {
|
||||
return super.getNewOverridableVar$production_sources_for_module_light_idea_test_case();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNewOverridableVar$production_sources_for_module_light_idea_test_case(int value) {
|
||||
super.setNewOverridableVar$production_sources_for_module_light_idea_test_case(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
sealed class X {
|
||||
internal abstract var newOverridableVar: Int
|
||||
|
||||
abstract class Y : X() {
|
||||
override var newOverridableVar: Int
|
||||
get() = 1
|
||||
set(value) {}
|
||||
}
|
||||
|
||||
class Z : Y() {
|
||||
override var newOverridableVar: Int
|
||||
get() = super.newOverridableVar
|
||||
set(value) { super.newOverridableVar = value }
|
||||
}
|
||||
}
|
||||
|
||||
fun get() : X? {
|
||||
return X.Z()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
get()?.newOverridableVar
|
||||
get()?.newOverridableVar = 3
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class J extends X.Y {
|
||||
@Override
|
||||
public int getOverridableVar$production_sources_for_module_light_idea_test_case() {
|
||||
return super.getOverridableVar$production_sources_for_module_light_idea_test_case();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverridableVar$production_sources_for_module_light_idea_test_case(int value) {
|
||||
super.setOverridableVar$production_sources_for_module_light_idea_test_case(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
sealed class X {
|
||||
internal abstract var /*rename*/overridableVar: Int
|
||||
|
||||
abstract class Y : X() {
|
||||
override var overridableVar: Int
|
||||
get() = 1
|
||||
set(value) {}
|
||||
}
|
||||
|
||||
class Z : Y() {
|
||||
override var overridableVar: Int
|
||||
get() = super.overridableVar
|
||||
set(value) { super.overridableVar = value }
|
||||
}
|
||||
}
|
||||
|
||||
fun get() : X? {
|
||||
return X.Z()
|
||||
}
|
||||
|
||||
fun test() {
|
||||
get()?.overridableVar
|
||||
get()?.overridableVar = 3
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"type": "MARKED_ELEMENT",
|
||||
"mainFile": "test.kt",
|
||||
"newName": "newOverridableVar"
|
||||
}
|
||||
+10
@@ -214,6 +214,16 @@ public class RenameTestGenerated extends AbstractRenameTest {
|
||||
runTest("idea/testData/refactoring/rename/importAliasByRef/importAliasByRef.test");
|
||||
}
|
||||
|
||||
@TestMetadata("internalFunWithOverrides/internalFunWithOverrides.test")
|
||||
public void testInternalFunWithOverrides_InternalFunWithOverrides() throws Exception {
|
||||
runTest("idea/testData/refactoring/rename/internalFunWithOverrides/internalFunWithOverrides.test");
|
||||
}
|
||||
|
||||
@TestMetadata("internalVarWithOverrides/internalFunWithOverrides.test")
|
||||
public void testInternalVarWithOverrides_InternalFunWithOverrides() throws Exception {
|
||||
runTest("idea/testData/refactoring/rename/internalVarWithOverrides/internalFunWithOverrides.test");
|
||||
}
|
||||
|
||||
@TestMetadata("javaClassImportAliasByRef/javaClassImportAliasByRef.test")
|
||||
public void testJavaClassImportAliasByRef_JavaClassImportAliasByRef() throws Exception {
|
||||
runTest("idea/testData/refactoring/rename/javaClassImportAliasByRef/javaClassImportAliasByRef.test");
|
||||
|
||||
Reference in New Issue
Block a user