Change Signature: Invalidate ChangeInfo after the refactoring
The goal is to avoid keeping all semantic information used by KotlinChangeInfo in UndoableAction produced by the refactoring #KT-17333 Fixed
This commit is contained in:
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 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.kotlin.idea.refactoring.changeSignature
|
||||||
|
|
||||||
|
import com.intellij.refactoring.changeSignature.ChangeInfo
|
||||||
|
|
||||||
|
class KotlinChangeInfoWrapper(delegate: KotlinChangeInfo) : ChangeInfo {
|
||||||
|
var delegate: KotlinChangeInfo? = delegate
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val method = delegate.method
|
||||||
|
|
||||||
|
override fun getMethod() = method
|
||||||
|
|
||||||
|
override fun isGenerateDelegate() = delegate!!.isGenerateDelegate
|
||||||
|
|
||||||
|
override fun getNewName() = delegate!!.newName
|
||||||
|
|
||||||
|
override fun isParameterTypesChanged() = delegate!!.isParameterTypesChanged
|
||||||
|
|
||||||
|
override fun getNewParameters() = delegate!!.newParameters
|
||||||
|
|
||||||
|
override fun isParameterSetOrOrderChanged() = delegate!!.isParameterSetOrOrderChanged
|
||||||
|
|
||||||
|
override fun isReturnTypeChanged() = delegate!!.isReturnTypeChanged
|
||||||
|
|
||||||
|
override fun isParameterNamesChanged() = delegate!!.isParameterNamesChanged
|
||||||
|
|
||||||
|
override fun isNameChanged() = delegate!!.isNameChanged
|
||||||
|
|
||||||
|
override fun getLanguage() = delegate!!.language
|
||||||
|
|
||||||
|
// Only getMethod() may be called after invalidate()
|
||||||
|
fun invalidate() {
|
||||||
|
delegate = null
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -232,5 +232,5 @@ class KotlinChangeSignature(project: Project,
|
|||||||
adjustedDescriptor,
|
adjustedDescriptor,
|
||||||
defaultValueContext
|
defaultValueContext
|
||||||
) as KotlinChangeSignatureProcessor
|
) as KotlinChangeSignatureProcessor
|
||||||
return processor.changeInfo
|
return processor.ktChangeInfo
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-6
@@ -36,19 +36,24 @@ import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinUsageI
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinWrapperForJavaUsageInfos
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinWrapperForJavaUsageInfos
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KotlinChangeSignatureProcessor(project: Project,
|
class KotlinChangeSignatureProcessor(
|
||||||
changeInfo: KotlinChangeInfo,
|
project: Project,
|
||||||
private val commandName: String) : ChangeSignatureProcessorBase(project, changeInfo) {
|
changeInfo: KotlinChangeInfo,
|
||||||
|
private val commandName: String
|
||||||
|
) : ChangeSignatureProcessorBase(project, KotlinChangeInfoWrapper(changeInfo)) {
|
||||||
|
val ktChangeInfo
|
||||||
|
get() = changeInfo.delegate!!
|
||||||
|
|
||||||
override fun createUsageViewDescriptor(usages: Array<UsageInfo>): UsageViewDescriptor {
|
override fun createUsageViewDescriptor(usages: Array<UsageInfo>): UsageViewDescriptor {
|
||||||
val subject = if (changeInfo.kind.isConstructor) "constructor" else "function"
|
val subject = if (ktChangeInfo.kind.isConstructor) "constructor" else "function"
|
||||||
return KotlinUsagesViewDescriptor(myChangeInfo.method, RefactoringBundle.message("0.to.change.signature", subject))
|
return KotlinUsagesViewDescriptor(myChangeInfo.method, RefactoringBundle.message("0.to.change.signature", subject))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChangeInfo() = super.getChangeInfo() as KotlinChangeInfo
|
override fun getChangeInfo() = super.getChangeInfo() as KotlinChangeInfoWrapper
|
||||||
|
|
||||||
override fun findUsages(): Array<UsageInfo> {
|
override fun findUsages(): Array<UsageInfo> {
|
||||||
val allUsages = ArrayList<UsageInfo>()
|
val allUsages = ArrayList<UsageInfo>()
|
||||||
changeInfo.getOrCreateJavaChangeInfos()?.let { javaChangeInfos ->
|
ktChangeInfo.getOrCreateJavaChangeInfos()?.let { javaChangeInfos ->
|
||||||
val javaProcessor = JavaChangeSignatureUsageProcessor()
|
val javaProcessor = JavaChangeSignatureUsageProcessor()
|
||||||
javaChangeInfos.mapTo(allUsages) {
|
javaChangeInfos.mapTo(allUsages) {
|
||||||
KotlinWrapperForJavaUsageInfos(it, javaProcessor.findUsages(it), changeInfo.method)
|
KotlinWrapperForJavaUsageInfos(it, javaProcessor.findUsages(it), changeInfo.method)
|
||||||
@@ -107,4 +112,13 @@ class KotlinChangeSignatureProcessor(project: Project,
|
|||||||
override fun isPreviewUsages(usages: Array<out UsageInfo>): Boolean = isPreviewUsages
|
override fun isPreviewUsages(usages: Array<out UsageInfo>): Boolean = isPreviewUsages
|
||||||
|
|
||||||
override fun getCommandName() = commandName
|
override fun getCommandName() = commandName
|
||||||
|
|
||||||
|
override fun performRefactoring(usages: Array<out UsageInfo>) {
|
||||||
|
try {
|
||||||
|
super.performRefactoring(usages)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
changeInfo.invalidate()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-15
@@ -100,8 +100,8 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
|
|
||||||
result.add(OriginalJavaMethodDescriptorWrapper(info.method))
|
result.add(OriginalJavaMethodDescriptorWrapper(info.method))
|
||||||
|
|
||||||
if (info is KotlinChangeInfo) {
|
if (info is KotlinChangeInfoWrapper) {
|
||||||
findAllMethodUsages(info, result)
|
findAllMethodUsages(info.delegate!!, result)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
findSAMUsages(info, result)
|
findSAMUsages(info, result)
|
||||||
@@ -507,13 +507,15 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
refUsages.set(adjustedUsages.toTypedArray())
|
refUsages.set(adjustedUsages.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info !is KotlinChangeInfo) return result
|
if (info !is KotlinChangeInfoWrapper) return result
|
||||||
|
|
||||||
|
val ktChangeInfo = info.delegate!!
|
||||||
|
|
||||||
val parameterNames = HashSet<String>()
|
val parameterNames = HashSet<String>()
|
||||||
val function = info.method
|
val function = info.method
|
||||||
val element = function
|
val element = function
|
||||||
val bindingContext = (element as KtElement).analyze(BodyResolveMode.FULL)
|
val bindingContext = (element as KtElement).analyze(BodyResolveMode.FULL)
|
||||||
val oldDescriptor = info.originalBaseFunctionDescriptor
|
val oldDescriptor = ktChangeInfo.originalBaseFunctionDescriptor
|
||||||
val containingDeclaration = oldDescriptor.containingDeclaration
|
val containingDeclaration = oldDescriptor.containingDeclaration
|
||||||
|
|
||||||
val parametersScope = when {
|
val parametersScope = when {
|
||||||
@@ -527,7 +529,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
|
|
||||||
val callableScope = oldDescriptor.getContainingScope()
|
val callableScope = oldDescriptor.getContainingScope()
|
||||||
|
|
||||||
val kind = info.kind
|
val kind = ktChangeInfo.kind
|
||||||
if (!kind.isConstructor && callableScope != null && !info.newName.isEmpty()) {
|
if (!kind.isConstructor && callableScope != null && !info.newName.isEmpty()) {
|
||||||
val newName = Name.identifier(info.newName)
|
val newName = Name.identifier(info.newName)
|
||||||
val conflicts = if (oldDescriptor is FunctionDescriptor)
|
val conflicts = if (oldDescriptor is FunctionDescriptor)
|
||||||
@@ -550,7 +552,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (parameter in info.getNonReceiverParameters()) {
|
for (parameter in ktChangeInfo.getNonReceiverParameters()) {
|
||||||
val valOrVar = parameter.valOrVar
|
val valOrVar = parameter.valOrVar
|
||||||
val parameterName = parameter.name
|
val parameterName = parameter.name
|
||||||
|
|
||||||
@@ -578,19 +580,19 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val newReceiverInfo = info.receiverParameterInfo
|
val newReceiverInfo = ktChangeInfo.receiverParameterInfo
|
||||||
val originalReceiverInfo = info.methodDescriptor.receiver
|
val originalReceiverInfo = ktChangeInfo.methodDescriptor.receiver
|
||||||
if (function is KtCallableDeclaration && newReceiverInfo != originalReceiverInfo) {
|
if (function is KtCallableDeclaration && newReceiverInfo != originalReceiverInfo) {
|
||||||
findReceiverIntroducingConflicts(result, function, newReceiverInfo)
|
findReceiverIntroducingConflicts(result, function, newReceiverInfo)
|
||||||
findInternalExplicitReceiverConflicts(refUsages.get(), result, originalReceiverInfo)
|
findInternalExplicitReceiverConflicts(refUsages.get(), result, originalReceiverInfo)
|
||||||
findReceiverToParameterInSafeCallsConflicts(refUsages.get(), result, info)
|
findReceiverToParameterInSafeCallsConflicts(refUsages.get(), result, ktChangeInfo)
|
||||||
findThisLabelConflicts(refUsages, result, info, function)
|
findThisLabelConflicts(refUsages, result, ktChangeInfo, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (usageInfo in usageInfos) {
|
for (usageInfo in usageInfos) {
|
||||||
if (usageInfo !is KotlinCallerUsage) continue
|
if (usageInfo !is KotlinCallerUsage) continue
|
||||||
val callerDescriptor = usageInfo.element?.resolveToDescriptorIfAny() ?: continue
|
val callerDescriptor = usageInfo.element?.resolveToDescriptorIfAny() ?: continue
|
||||||
findParameterDuplicationInCaller(result, info, usageInfo.element!!, callerDescriptor)
|
findParameterDuplicationInCaller(result, ktChangeInfo, usageInfo.element!!, callerDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -823,9 +825,10 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
val isJavaMethodUsage = isJavaMethodUsage(usageInfo)
|
val isJavaMethodUsage = isJavaMethodUsage(usageInfo)
|
||||||
|
|
||||||
if (usageInfo is KotlinWrapperForJavaUsageInfos) {
|
if (usageInfo is KotlinWrapperForJavaUsageInfos) {
|
||||||
val javaChangeInfos = (changeInfo as KotlinChangeInfo).getOrCreateJavaChangeInfos() ?: return true
|
val ktChangeInfo = (changeInfo as KotlinChangeInfoWrapper).delegate!!
|
||||||
|
val javaChangeInfos = ktChangeInfo.getOrCreateJavaChangeInfos() ?: return true
|
||||||
javaChangeInfos.firstOrNull {
|
javaChangeInfos.firstOrNull {
|
||||||
changeInfo.originalToCurrentMethods[usageInfo.javaChangeInfo.method] == it.method
|
ktChangeInfo.originalToCurrentMethods[usageInfo.javaChangeInfo.method] == it.method
|
||||||
}?.let { javaChangeInfo ->
|
}?.let { javaChangeInfo ->
|
||||||
val nullabilityPropagator = NullabilityPropagator(javaChangeInfo.method)
|
val nullabilityPropagator = NullabilityPropagator(javaChangeInfo.method)
|
||||||
val javaUsageInfos = usageInfo.javaUsageInfos
|
val javaUsageInfos = usageInfo.javaUsageInfos
|
||||||
@@ -910,12 +913,12 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return (usageInfo as? KotlinUsageInfo<PsiElement>)?.processUsage(changeInfo as KotlinChangeInfo, element, usages) ?: false
|
return (usageInfo as? KotlinUsageInfo<PsiElement>)?.processUsage((changeInfo as KotlinChangeInfoWrapper).delegate!!, element, usages) ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processPrimaryMethod(changeInfo: ChangeInfo): Boolean {
|
override fun processPrimaryMethod(changeInfo: ChangeInfo): Boolean {
|
||||||
val ktChangeInfo = when (changeInfo) {
|
val ktChangeInfo = when (changeInfo) {
|
||||||
is KotlinChangeInfo -> changeInfo
|
is KotlinChangeInfoWrapper -> changeInfo.delegate!!
|
||||||
is JavaChangeInfo -> {
|
is JavaChangeInfo -> {
|
||||||
val method = changeInfo.method as? KtLightMethod ?: return false
|
val method = changeInfo.method as? KtLightMethod ?: return false
|
||||||
var baseFunction = method.kotlinOrigin ?: return false
|
var baseFunction = method.kotlinOrigin ?: return false
|
||||||
|
|||||||
Reference in New Issue
Block a user