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,
|
||||
defaultValueContext
|
||||
) 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 java.util.*
|
||||
|
||||
class KotlinChangeSignatureProcessor(project: Project,
|
||||
changeInfo: KotlinChangeInfo,
|
||||
private val commandName: String) : ChangeSignatureProcessorBase(project, changeInfo) {
|
||||
class KotlinChangeSignatureProcessor(
|
||||
project: Project,
|
||||
changeInfo: KotlinChangeInfo,
|
||||
private val commandName: String
|
||||
) : ChangeSignatureProcessorBase(project, KotlinChangeInfoWrapper(changeInfo)) {
|
||||
val ktChangeInfo
|
||||
get() = changeInfo.delegate!!
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
override fun getChangeInfo() = super.getChangeInfo() as KotlinChangeInfo
|
||||
override fun getChangeInfo() = super.getChangeInfo() as KotlinChangeInfoWrapper
|
||||
|
||||
override fun findUsages(): Array<UsageInfo> {
|
||||
val allUsages = ArrayList<UsageInfo>()
|
||||
changeInfo.getOrCreateJavaChangeInfos()?.let { javaChangeInfos ->
|
||||
ktChangeInfo.getOrCreateJavaChangeInfos()?.let { javaChangeInfos ->
|
||||
val javaProcessor = JavaChangeSignatureUsageProcessor()
|
||||
javaChangeInfos.mapTo(allUsages) {
|
||||
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 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))
|
||||
|
||||
if (info is KotlinChangeInfo) {
|
||||
findAllMethodUsages(info, result)
|
||||
if (info is KotlinChangeInfoWrapper) {
|
||||
findAllMethodUsages(info.delegate!!, result)
|
||||
}
|
||||
else {
|
||||
findSAMUsages(info, result)
|
||||
@@ -507,13 +507,15 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
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 function = info.method
|
||||
val element = function
|
||||
val bindingContext = (element as KtElement).analyze(BodyResolveMode.FULL)
|
||||
val oldDescriptor = info.originalBaseFunctionDescriptor
|
||||
val oldDescriptor = ktChangeInfo.originalBaseFunctionDescriptor
|
||||
val containingDeclaration = oldDescriptor.containingDeclaration
|
||||
|
||||
val parametersScope = when {
|
||||
@@ -527,7 +529,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
|
||||
val callableScope = oldDescriptor.getContainingScope()
|
||||
|
||||
val kind = info.kind
|
||||
val kind = ktChangeInfo.kind
|
||||
if (!kind.isConstructor && callableScope != null && !info.newName.isEmpty()) {
|
||||
val newName = Name.identifier(info.newName)
|
||||
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 parameterName = parameter.name
|
||||
|
||||
@@ -578,19 +580,19 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
val newReceiverInfo = info.receiverParameterInfo
|
||||
val originalReceiverInfo = info.methodDescriptor.receiver
|
||||
val newReceiverInfo = ktChangeInfo.receiverParameterInfo
|
||||
val originalReceiverInfo = ktChangeInfo.methodDescriptor.receiver
|
||||
if (function is KtCallableDeclaration && newReceiverInfo != originalReceiverInfo) {
|
||||
findReceiverIntroducingConflicts(result, function, newReceiverInfo)
|
||||
findInternalExplicitReceiverConflicts(refUsages.get(), result, originalReceiverInfo)
|
||||
findReceiverToParameterInSafeCallsConflicts(refUsages.get(), result, info)
|
||||
findThisLabelConflicts(refUsages, result, info, function)
|
||||
findReceiverToParameterInSafeCallsConflicts(refUsages.get(), result, ktChangeInfo)
|
||||
findThisLabelConflicts(refUsages, result, ktChangeInfo, function)
|
||||
}
|
||||
|
||||
for (usageInfo in usageInfos) {
|
||||
if (usageInfo !is KotlinCallerUsage) continue
|
||||
val callerDescriptor = usageInfo.element?.resolveToDescriptorIfAny() ?: continue
|
||||
findParameterDuplicationInCaller(result, info, usageInfo.element!!, callerDescriptor)
|
||||
findParameterDuplicationInCaller(result, ktChangeInfo, usageInfo.element!!, callerDescriptor)
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -823,9 +825,10 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
val isJavaMethodUsage = isJavaMethodUsage(usageInfo)
|
||||
|
||||
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 {
|
||||
changeInfo.originalToCurrentMethods[usageInfo.javaChangeInfo.method] == it.method
|
||||
ktChangeInfo.originalToCurrentMethods[usageInfo.javaChangeInfo.method] == it.method
|
||||
}?.let { javaChangeInfo ->
|
||||
val nullabilityPropagator = NullabilityPropagator(javaChangeInfo.method)
|
||||
val javaUsageInfos = usageInfo.javaUsageInfos
|
||||
@@ -910,12 +913,12 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
}
|
||||
|
||||
@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 {
|
||||
val ktChangeInfo = when (changeInfo) {
|
||||
is KotlinChangeInfo -> changeInfo
|
||||
is KotlinChangeInfoWrapper -> changeInfo.delegate!!
|
||||
is JavaChangeInfo -> {
|
||||
val method = changeInfo.method as? KtLightMethod ?: return false
|
||||
var baseFunction = method.kotlinOrigin ?: return false
|
||||
|
||||
Reference in New Issue
Block a user