Change Signature: Property support
#KT-6599 Fixed
This commit is contained in:
@@ -270,7 +270,7 @@ usageType.packageMemberAccess = Package member access
|
|||||||
|
|
||||||
x.in.y={0} in {1}
|
x.in.y={0} in {1}
|
||||||
x.implements.y={0} in {1} implements {2} in {3}.
|
x.implements.y={0} in {1} implements {2} in {3}.
|
||||||
x.overrides.y.in.class.list={0} in {1} overrides functions in the following classes/interfaces: {2} Do you want to {3} the base functions?
|
x.overrides.y.in.class.list={0} in {1} overrides declarations in the following classes/interfaces: {2} Do you want to {3} the base declarations?
|
||||||
|
|
||||||
unused.overriding.methods.title=Unused Overriding Members
|
unused.overriding.methods.title=Unused Overriding Members
|
||||||
there.are.unused.methods.that.override.methods.you.delete=There are unused members that override methods you delete.
|
there.are.unused.methods.that.override.methods.you.delete=There are unused members that override methods you delete.
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetParameterInfo parameterInfo =
|
JetParameterInfo parameterInfo =
|
||||||
getNewParameterInfo(originalDescriptor.getBaseDescriptor(), bindingContext, argument, validator);
|
getNewParameterInfo((FunctionDescriptor) originalDescriptor.getBaseDescriptor(), bindingContext, argument, validator);
|
||||||
typesToShorten.add(parameterInfo.getOriginalType());
|
typesToShorten.add(parameterInfo.getOriginalType());
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
|
|||||||
+1
-1
@@ -115,7 +115,7 @@ object CreateParameterActionFactory: JetSingleIntentionActionFactory() {
|
|||||||
return CreateParameterFromUsageFix(
|
return CreateParameterFromUsageFix(
|
||||||
functionDescriptor,
|
functionDescriptor,
|
||||||
context,
|
context,
|
||||||
JetParameterInfo(functionDescriptor = functionDescriptor,
|
JetParameterInfo(callableDescriptor = functionDescriptor,
|
||||||
name = refExpr.getReferencedName(),
|
name = refExpr.getReferencedName(),
|
||||||
type = paramType,
|
type = paramType,
|
||||||
valOrVar = valOrVar),
|
valOrVar = valOrVar),
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ public object CreateParameterByNamedArgumentActionFactory: JetSingleIntentionAct
|
|||||||
if (paramType.hasTypeParametersToAdd(functionDescriptor, context)) return null
|
if (paramType.hasTypeParametersToAdd(functionDescriptor, context)) return null
|
||||||
|
|
||||||
val parameterInfo = JetParameterInfo(
|
val parameterInfo = JetParameterInfo(
|
||||||
functionDescriptor = functionDescriptor,
|
callableDescriptor = functionDescriptor,
|
||||||
name = name,
|
name = name,
|
||||||
type = paramType,
|
type = paramType,
|
||||||
defaultValueForCall = argumentExpression
|
defaultValueForCall = argumentExpression
|
||||||
|
|||||||
@@ -19,28 +19,35 @@ package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
|||||||
import com.intellij.lang.Language
|
import com.intellij.lang.Language
|
||||||
import com.intellij.lang.java.JavaLanguage
|
import com.intellij.lang.java.JavaLanguage
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.refactoring.changeSignature.*
|
import com.intellij.refactoring.changeSignature.ChangeInfo
|
||||||
|
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor
|
||||||
|
import com.intellij.refactoring.changeSignature.JavaChangeInfo
|
||||||
|
import com.intellij.refactoring.changeSignature.ParameterInfoImpl
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.VisibilityUtil
|
import com.intellij.util.VisibilityUtil
|
||||||
import org.jetbrains.kotlin.asJava.*
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.codegen.PropertyCodegen
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.idea.JetLanguage
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.getJavaMethodDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.core.refactoring.j2k
|
||||||
|
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMethodDescriptor.Kind
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetCallableDefinitionUsage
|
||||||
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
|
||||||
import org.jetbrains.kotlin.idea.JetLanguage
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.*
|
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.j2k
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
|
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|
||||||
import java.util.HashMap
|
|
||||||
import kotlin.properties.Delegates
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
import org.jetbrains.kotlin.idea.project.*
|
import java.util.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import kotlin.properties.Delegates
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMethodDescriptor.Kind
|
|
||||||
|
|
||||||
public class JetChangeInfo(
|
public class JetChangeInfo(
|
||||||
val methodDescriptor: JetMethodDescriptor,
|
val methodDescriptor: JetMethodDescriptor,
|
||||||
@@ -61,7 +68,7 @@ public class JetChangeInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val newParameters = parameterInfos.toArrayList()
|
private val newParameters = parameterInfos.toArrayList()
|
||||||
private val originalPsiMethod: PsiMethod? = getCurrentPsiMethod()
|
private val originalPsiMethods: List<PsiMethod> = getMethod().toLightMethods()
|
||||||
|
|
||||||
private val oldNameToParameterIndex: Map<String, Int> by Delegates.lazy {
|
private val oldNameToParameterIndex: Map<String, Int> by Delegates.lazy {
|
||||||
val map = HashMap<String, Int>()
|
val map = HashMap<String, Int>()
|
||||||
@@ -80,13 +87,7 @@ public class JetChangeInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var isPrimaryMethodUpdated: Boolean = false
|
private var isPrimaryMethodUpdated: Boolean = false
|
||||||
private var javaChangeInfo: JavaChangeInfo? = null
|
private var javaChangeInfos: List<JavaChangeInfo>? = null
|
||||||
|
|
||||||
private fun getCurrentPsiMethod(): PsiMethod? {
|
|
||||||
val psiMethods = getMethod().toLightMethods()
|
|
||||||
assert(psiMethods.size() <= 1) { "Multiple light methods: " + getMethod().getText() }
|
|
||||||
return psiMethods.firstOrNull()
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun getOldParameterIndex(oldParameterName: String): Int? = oldNameToParameterIndex[oldParameterName]
|
public fun getOldParameterIndex(oldParameterName: String): Int? = oldNameToParameterIndex[oldParameterName]
|
||||||
|
|
||||||
@@ -103,6 +104,7 @@ public class JetChangeInfo(
|
|||||||
fun getNonReceiverParametersCount(): Int = newParameters.size() - (if (receiverParameterInfo != null) 1 else 0)
|
fun getNonReceiverParametersCount(): Int = newParameters.size() - (if (receiverParameterInfo != null) 1 else 0)
|
||||||
|
|
||||||
fun getNonReceiverParameters(): List<JetParameterInfo> {
|
fun getNonReceiverParameters(): List<JetParameterInfo> {
|
||||||
|
if (methodDescriptor.baseDeclaration is JetProperty) return emptyList()
|
||||||
return receiverParameterInfo?.let { receiver -> newParameters.filter { it != receiver } } ?: newParameters
|
return receiverParameterInfo?.let { receiver -> newParameters.filter { it != receiver } } ?: newParameters
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +148,7 @@ public class JetChangeInfo(
|
|||||||
|
|
||||||
override fun getLanguage(): Language = JetLanguage.INSTANCE
|
override fun getLanguage(): Language = JetLanguage.INSTANCE
|
||||||
|
|
||||||
public fun getNewSignature(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
|
public fun getNewSignature(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String {
|
||||||
val buffer = StringBuilder()
|
val buffer = StringBuilder()
|
||||||
|
|
||||||
val defaultVisibility = if (kind.isConstructor) Visibilities.PUBLIC else Visibilities.INTERNAL
|
val defaultVisibility = if (kind.isConstructor) Visibilities.PUBLIC else Visibilities.INTERNAL
|
||||||
@@ -174,7 +176,7 @@ public class JetChangeInfo(
|
|||||||
buffer.append(name)
|
buffer.append(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.append(getNewParametersSignature(inheritedFunction))
|
buffer.append(getNewParametersSignature(inheritedCallable))
|
||||||
|
|
||||||
if (newReturnType != null && !KotlinBuiltIns.isUnit(newReturnType) && kind == Kind.FUNCTION)
|
if (newReturnType != null && !KotlinBuiltIns.isUnit(newReturnType) && kind == Kind.FUNCTION)
|
||||||
buffer.append(": ").append(newReturnTypeText)
|
buffer.append(": ").append(newReturnTypeText)
|
||||||
@@ -182,63 +184,75 @@ public class JetChangeInfo(
|
|||||||
return buffer.toString()
|
return buffer.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun isRefactoringTarget(inheritedFunctionDescriptor: FunctionDescriptor?): Boolean {
|
public fun isRefactoringTarget(inheritedCallableDescriptor: CallableDescriptor?): Boolean {
|
||||||
return inheritedFunctionDescriptor != null
|
return inheritedCallableDescriptor != null
|
||||||
&& getMethod() == DescriptorToSourceUtils.descriptorToDeclaration(inheritedFunctionDescriptor)
|
&& getMethod() == DescriptorToSourceUtils.descriptorToDeclaration(inheritedCallableDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getNewParametersSignature(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
|
public fun getNewParametersSignature(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String {
|
||||||
val signatureParameters = getNonReceiverParameters()
|
val signatureParameters = getNonReceiverParameters()
|
||||||
|
|
||||||
val isLambda = inheritedFunction.getDeclaration() is JetFunctionLiteral
|
val isLambda = inheritedCallable.getDeclaration() is JetFunctionLiteral
|
||||||
if (isLambda && signatureParameters.size() == 1 && !signatureParameters.get(0).requiresExplicitType(inheritedFunction)) {
|
if (isLambda && signatureParameters.size() == 1 && !signatureParameters.get(0).requiresExplicitType(inheritedCallable)) {
|
||||||
return signatureParameters.get(0).getDeclarationSignature(0, inheritedFunction)
|
return signatureParameters.get(0).getDeclarationSignature(0, inheritedCallable)
|
||||||
}
|
}
|
||||||
|
|
||||||
return signatureParameters.indices
|
return signatureParameters.indices
|
||||||
.map { i -> signatureParameters[i].getDeclarationSignature(i, inheritedFunction) }
|
.map { i -> signatureParameters[i].getDeclarationSignature(i, inheritedCallable) }
|
||||||
.joinToString(prefix = "(", separator = ", ", postfix = ")")
|
.joinToString(prefix = "(", separator = ", ", postfix = ")")
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun renderReceiverType(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String? {
|
public fun renderReceiverType(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String? {
|
||||||
val receiverTypeText = receiverParameterInfo?.currentTypeText ?: return null
|
val receiverTypeText = receiverParameterInfo?.currentTypeText ?: return null
|
||||||
val typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor() ?: return receiverTypeText
|
val typeSubstitutor = inheritedCallable.getOrCreateTypeSubstitutor() ?: return receiverTypeText
|
||||||
val currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor() ?: return receiverTypeText
|
val currentBaseFunction = inheritedCallable.getBaseFunction().getCurrentCallableDescriptor() ?: return receiverTypeText
|
||||||
return currentBaseFunction.getExtensionReceiverParameter()!!.getType().renderTypeWithSubstitution(typeSubstitutor, receiverTypeText, false)
|
return currentBaseFunction.getExtensionReceiverParameter()!!.getType().renderTypeWithSubstitution(typeSubstitutor, receiverTypeText, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun renderReturnType(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
|
public fun renderReturnType(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String {
|
||||||
val typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor() ?: return newReturnTypeText
|
val typeSubstitutor = inheritedCallable.getOrCreateTypeSubstitutor() ?: return newReturnTypeText
|
||||||
val currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor() ?: return newReturnTypeText
|
val currentBaseFunction = inheritedCallable.getBaseFunction().getCurrentCallableDescriptor() ?: return newReturnTypeText
|
||||||
return currentBaseFunction.getReturnType().renderTypeWithSubstitution(typeSubstitutor, newReturnTypeText, false)
|
return currentBaseFunction.getReturnType().renderTypeWithSubstitution(typeSubstitutor, newReturnTypeText, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun primaryMethodUpdated() {
|
public fun primaryMethodUpdated() {
|
||||||
isPrimaryMethodUpdated = true
|
isPrimaryMethodUpdated = true
|
||||||
javaChangeInfo = null
|
javaChangeInfos = null
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getOrCreateJavaChangeInfo(): JavaChangeInfo? {
|
public fun getOrCreateJavaChangeInfos(): List<JavaChangeInfo>? {
|
||||||
if (ProjectStructureUtil.isJsKotlinModule(getMethod().getContainingFile() as JetFile)) return null
|
/*
|
||||||
|
* When primaryMethodUpdated is false, changes to the primary Kotlin declaration are already confirmed, but not yet applied.
|
||||||
|
* It means that originalPsiMethod has already expired, but new one can't be created until Kotlin declaration is updated
|
||||||
|
* (signified by primaryMethodUpdated being true). It means we can't know actual PsiType, visibility, etc.
|
||||||
|
* to use in JavaChangeInfo. However they are not actually used at this point since only parameter count and order matters here
|
||||||
|
* So we resort to this hack and pass around "default" type (void) and visibility (package-local)
|
||||||
|
*/
|
||||||
|
|
||||||
if (javaChangeInfo == null) {
|
fun createJavaChangeInfo(originalPsiMethod: PsiMethod,
|
||||||
val currentPsiMethod = getCurrentPsiMethod()
|
currentPsiMethod: PsiMethod,
|
||||||
if (originalPsiMethod == null || currentPsiMethod == null) return null
|
newName: String,
|
||||||
|
newReturnType: PsiType?,
|
||||||
/*
|
newParameters: Array<ParameterInfoImpl>
|
||||||
* When primaryMethodUpdated is false, changes to the primary Kotlin declaration are already confirmed, but not yet applied.
|
): JavaChangeInfo? {
|
||||||
* It means that originalPsiMethod has already expired, but new one can't be created until Kotlin declaration is updated
|
val newVisibility = if (isPrimaryMethodUpdated)
|
||||||
* (signified by primaryMethodUpdated being true). It means we can't know actual PsiType, visibility, etc.
|
|
||||||
* to use in JavaChangeInfo. However they are not actually used at this point since only parameter count and order matters here
|
|
||||||
* So we resort to this hack and pass around "default" type (void) and visibility (package-local)
|
|
||||||
*/
|
|
||||||
val javaVisibility = if (isPrimaryMethodUpdated)
|
|
||||||
VisibilityUtil.getVisibilityModifier(currentPsiMethod.getModifierList())
|
VisibilityUtil.getVisibilityModifier(currentPsiMethod.getModifierList())
|
||||||
else
|
else
|
||||||
PsiModifier.PACKAGE_LOCAL
|
PsiModifier.PACKAGE_LOCAL
|
||||||
|
val javaChangeInfo = ChangeSignatureProcessor(getMethod().getProject(),
|
||||||
|
originalPsiMethod,
|
||||||
|
false,
|
||||||
|
newVisibility,
|
||||||
|
newName,
|
||||||
|
newReturnType ?: PsiType.VOID,
|
||||||
|
newParameters).getChangeInfo()
|
||||||
|
javaChangeInfo.updateMethod(currentPsiMethod)
|
||||||
|
|
||||||
val newParameterList = receiverParameterInfo.singletonOrEmptyList() + getNonReceiverParameters()
|
return javaChangeInfo
|
||||||
val newJavaParameters = newParameterList.withIndex().map { pair ->
|
}
|
||||||
|
|
||||||
|
fun getJavaParameterInfos(currentPsiMethod: PsiMethod, newParameterList: List<JetParameterInfo>): MutableList<ParameterInfoImpl> {
|
||||||
|
return newParameterList.withIndex().mapTo(ArrayList()) { pair ->
|
||||||
val (i, info) = pair
|
val (i, info) = pair
|
||||||
|
|
||||||
val type = if (isPrimaryMethodUpdated)
|
val type = if (isPrimaryMethodUpdated)
|
||||||
@@ -255,25 +269,66 @@ public class JetChangeInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParameterInfoImpl(javaOldIndex, info.getName(), type, info.defaultValueForCall?.getText() ?: "")
|
ParameterInfoImpl(javaOldIndex, info.getName(), type, info.defaultValueForCall?.getText() ?: "")
|
||||||
}.toTypedArray()
|
}
|
||||||
|
|
||||||
val returnType = if (isPrimaryMethodUpdated) currentPsiMethod.getReturnType() else PsiType.VOID
|
|
||||||
|
|
||||||
javaChangeInfo = ChangeSignatureProcessor(getMethod().getProject(),
|
|
||||||
originalPsiMethod,
|
|
||||||
false,
|
|
||||||
javaVisibility,
|
|
||||||
getNewName(),
|
|
||||||
returnType,
|
|
||||||
newJavaParameters).getChangeInfo()
|
|
||||||
javaChangeInfo!!.updateMethod(currentPsiMethod)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return javaChangeInfo
|
fun createJavaChangeInfoForFunctionOrGetter(
|
||||||
|
originalPsiMethod: PsiMethod,
|
||||||
|
currentPsiMethod: PsiMethod,
|
||||||
|
isGetter: Boolean
|
||||||
|
): JavaChangeInfo? {
|
||||||
|
val newParameterList = receiverParameterInfo.singletonOrEmptyList() + getNonReceiverParameters()
|
||||||
|
val newJavaParameters = getJavaParameterInfos(currentPsiMethod, newParameterList).toTypedArray()
|
||||||
|
val newName = if (isGetter) PropertyCodegen.getterName(Name.identifier(getNewName())) else getNewName()
|
||||||
|
return createJavaChangeInfo(originalPsiMethod, currentPsiMethod, newName, currentPsiMethod.getReturnType(), newJavaParameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createJavaChangeInfoForSetter(originalPsiMethod: PsiMethod, currentPsiMethod: PsiMethod): JavaChangeInfo? {
|
||||||
|
val newJavaParameters = getJavaParameterInfos(currentPsiMethod, receiverParameterInfo.singletonOrEmptyList())
|
||||||
|
val oldIndex = if (methodDescriptor.receiver != null) 1 else 0
|
||||||
|
if (isPrimaryMethodUpdated) {
|
||||||
|
val newIndex = if (receiverParameterInfo != null) 1 else 0
|
||||||
|
val setterParameter = currentPsiMethod.getParameterList().getParameters()[newIndex]
|
||||||
|
newJavaParameters.add(ParameterInfoImpl(oldIndex, setterParameter.getName(), setterParameter.getType()))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newJavaParameters.add(ParameterInfoImpl(oldIndex, "receiver", PsiType.VOID))
|
||||||
|
}
|
||||||
|
|
||||||
|
val newName = PropertyCodegen.setterName(Name.identifier(getNewName()))
|
||||||
|
return createJavaChangeInfo(originalPsiMethod, currentPsiMethod, newName, PsiType.VOID, newJavaParameters.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProjectStructureUtil.isJsKotlinModule(getMethod().getContainingFile() as JetFile)) return null
|
||||||
|
|
||||||
|
if (javaChangeInfos == null) {
|
||||||
|
val method = getMethod()
|
||||||
|
javaChangeInfos = (originalPsiMethods zip method.toLightMethods()).map {
|
||||||
|
val (originalPsiMethod, currentPsiMethod) = it
|
||||||
|
|
||||||
|
when (method) {
|
||||||
|
is JetFunction, is JetClassOrObject ->
|
||||||
|
createJavaChangeInfoForFunctionOrGetter(originalPsiMethod, currentPsiMethod, false)
|
||||||
|
is JetProperty -> {
|
||||||
|
val accessorName = originalPsiMethod.getName()
|
||||||
|
when {
|
||||||
|
accessorName.startsWith(JvmAbi.GETTER_PREFIX) ->
|
||||||
|
createJavaChangeInfoForFunctionOrGetter(originalPsiMethod, currentPsiMethod, true)
|
||||||
|
accessorName.startsWith(JvmAbi.SETTER_PREFIX) ->
|
||||||
|
createJavaChangeInfoForSetter(originalPsiMethod, currentPsiMethod)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}.filterNotNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
return javaChangeInfos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public val JetChangeInfo.originalBaseFunctionDescriptor: FunctionDescriptor
|
public val JetChangeInfo.originalBaseFunctionDescriptor: CallableDescriptor
|
||||||
get() = methodDescriptor.baseDescriptor
|
get() = methodDescriptor.baseDescriptor
|
||||||
|
|
||||||
public val JetChangeInfo.kind: Kind get() = methodDescriptor.kind
|
public val JetChangeInfo.kind: Kind get() = methodDescriptor.kind
|
||||||
@@ -281,7 +336,7 @@ public val JetChangeInfo.kind: Kind get() = methodDescriptor.kind
|
|||||||
public val JetChangeInfo.oldName: String?
|
public val JetChangeInfo.oldName: String?
|
||||||
get() = (methodDescriptor.getMethod() as? JetFunction)?.getName()
|
get() = (methodDescriptor.getMethod() as? JetFunction)?.getName()
|
||||||
|
|
||||||
public val JetChangeInfo.affectedFunctions: Collection<UsageInfo> get() = methodDescriptor.affectedFunctions
|
public val JetChangeInfo.affectedFunctions: Collection<UsageInfo> get() = methodDescriptor.affectedCallables
|
||||||
|
|
||||||
public fun ChangeInfo.toJetChangeInfo(originalChangeSignatureDescriptor: JetMethodDescriptor): JetChangeInfo {
|
public fun ChangeInfo.toJetChangeInfo(originalChangeSignatureDescriptor: JetMethodDescriptor): JetChangeInfo {
|
||||||
val method = getMethod() as PsiMethod
|
val method = getMethod() as PsiMethod
|
||||||
@@ -305,7 +360,7 @@ public fun ChangeInfo.toJetChangeInfo(originalChangeSignatureDescriptor: JetMeth
|
|||||||
}
|
}
|
||||||
else null
|
else null
|
||||||
|
|
||||||
with(JetParameterInfo(functionDescriptor = functionDescriptor,
|
with(JetParameterInfo(callableDescriptor = functionDescriptor,
|
||||||
originalIndex = oldIndex,
|
originalIndex = oldIndex,
|
||||||
name = info.getName(),
|
name = info.getName(),
|
||||||
type = if (oldIndex >= 0) originalParameterDescriptors[oldIndex].getType() else currentType,
|
type = if (oldIndex >= 0) originalParameterDescriptors[oldIndex].getType() else currentType,
|
||||||
|
|||||||
+174
@@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.openapi.options.ConfigurationException
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiDocumentManager
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
|
import com.intellij.refactoring.ui.ComboBoxVisibilityPanel
|
||||||
|
import com.intellij.refactoring.ui.RefactoringDialog
|
||||||
|
import com.intellij.ui.EditorTextField
|
||||||
|
import com.intellij.ui.NonFocusableCheckBox
|
||||||
|
import com.intellij.util.ui.FormBuilder
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.idea.JetFileType
|
||||||
|
import org.jetbrains.kotlin.idea.core.refactoring.validateElement
|
||||||
|
import org.jetbrains.kotlin.psi.JetExpression
|
||||||
|
import org.jetbrains.kotlin.psi.JetProperty
|
||||||
|
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||||
|
import org.jetbrains.kotlin.psi.JetTypeCodeFragment
|
||||||
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||||
|
import javax.swing.JCheckBox
|
||||||
|
import javax.swing.JComboBox
|
||||||
|
import javax.swing.JComponent
|
||||||
|
import javax.swing.JLabel
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
public class JetChangePropertySignatureDialog(
|
||||||
|
project: Project,
|
||||||
|
private val methodDescriptor: JetMethodDescriptor,
|
||||||
|
private val commandName: String?
|
||||||
|
): RefactoringDialog(project, true) {
|
||||||
|
private val visibilityCombo = JComboBox(
|
||||||
|
arrayOf(Visibilities.INTERNAL, Visibilities.PRIVATE, Visibilities.PROTECTED, Visibilities.PUBLIC)
|
||||||
|
)
|
||||||
|
private val nameField = EditorTextField(methodDescriptor.getName())
|
||||||
|
private var returnTypeField: EditorTextField by Delegates.notNull()
|
||||||
|
private var receiverTypeCheckBox: JCheckBox by Delegates.notNull()
|
||||||
|
var receiverTypeLabel: JLabel by Delegates.notNull()
|
||||||
|
private var receiverTypeField: EditorTextField by Delegates.notNull()
|
||||||
|
var receiverDefaultValueLabel: JLabel? = null
|
||||||
|
private var receiverDefaultValueField: EditorTextField? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
setTitle("Change Signature")
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPreferredFocusedComponent() = nameField
|
||||||
|
|
||||||
|
override fun createCenterPanel(): JComponent? {
|
||||||
|
fun updateReceiverUI() {
|
||||||
|
val withReceiver = receiverTypeCheckBox.isSelected()
|
||||||
|
receiverTypeLabel.setEnabled(withReceiver)
|
||||||
|
receiverTypeField.setEnabled(withReceiver)
|
||||||
|
receiverDefaultValueLabel?.setEnabled(withReceiver)
|
||||||
|
receiverDefaultValueField?.setEnabled(withReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
val documentManager = PsiDocumentManager.getInstance(myProject)
|
||||||
|
val psiFactory = JetPsiFactory(myProject)
|
||||||
|
|
||||||
|
return with(FormBuilder.createFormBuilder()) {
|
||||||
|
if (!((methodDescriptor.baseDeclaration as? JetProperty)?.isLocal() ?: false)) {
|
||||||
|
visibilityCombo.setSelectedItem(methodDescriptor.getVisibility())
|
||||||
|
addLabeledComponent("&Visibility: ", visibilityCombo)
|
||||||
|
}
|
||||||
|
|
||||||
|
addLabeledComponent("&Name: ", nameField)
|
||||||
|
|
||||||
|
val returnTypeCodeFragment = psiFactory.createTypeCodeFragment(methodDescriptor.renderOriginalReturnType(),
|
||||||
|
methodDescriptor.baseDeclaration)
|
||||||
|
returnTypeField = EditorTextField(documentManager.getDocument(returnTypeCodeFragment), myProject, JetFileType.INSTANCE)
|
||||||
|
addLabeledComponent("&Type: ", returnTypeField)
|
||||||
|
|
||||||
|
addSeparator()
|
||||||
|
|
||||||
|
val receiverTypeCheckBox = JCheckBox("Extension property: ")
|
||||||
|
receiverTypeCheckBox.setMnemonic('x')
|
||||||
|
receiverTypeCheckBox.addActionListener { updateReceiverUI() }
|
||||||
|
receiverTypeCheckBox.setSelected(methodDescriptor.receiver != null)
|
||||||
|
addComponent(receiverTypeCheckBox)
|
||||||
|
this@JetChangePropertySignatureDialog.receiverTypeCheckBox = receiverTypeCheckBox
|
||||||
|
|
||||||
|
val receiverTypeCodeFragment = psiFactory.createTypeCodeFragment(methodDescriptor.renderOriginalReceiverType() ?: "",
|
||||||
|
methodDescriptor.baseDeclaration)
|
||||||
|
receiverTypeField = EditorTextField(documentManager.getDocument(receiverTypeCodeFragment), myProject, JetFileType.INSTANCE)
|
||||||
|
receiverTypeLabel = JLabel("Receiver type: ")
|
||||||
|
receiverTypeLabel.setDisplayedMnemonic('t')
|
||||||
|
addLabeledComponent(receiverTypeLabel, receiverTypeField)
|
||||||
|
|
||||||
|
if (methodDescriptor.receiver == null) {
|
||||||
|
val receiverDefaultValueCodeFragment = psiFactory.createExpressionCodeFragment("", methodDescriptor.baseDeclaration)
|
||||||
|
receiverDefaultValueField = EditorTextField(documentManager.getDocument(receiverDefaultValueCodeFragment),
|
||||||
|
myProject,
|
||||||
|
JetFileType.INSTANCE)
|
||||||
|
receiverDefaultValueLabel = JLabel("Default receiver value: ")
|
||||||
|
receiverDefaultValueLabel!!.setDisplayedMnemonic('D')
|
||||||
|
addLabeledComponent(receiverDefaultValueLabel, receiverDefaultValueField!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateReceiverUI()
|
||||||
|
|
||||||
|
getPanel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDefaultReceiverValue(): JetExpression? {
|
||||||
|
val receiverDefaultValue = receiverDefaultValueField?.getText() ?: ""
|
||||||
|
return if (receiverDefaultValue.isNotEmpty()) JetPsiFactory(myProject).createExpression(receiverDefaultValue) else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canRun() {
|
||||||
|
val psiFactory = JetPsiFactory(myProject)
|
||||||
|
|
||||||
|
psiFactory.createSimpleName(nameField.getText()).validateElement("Invalid name")
|
||||||
|
psiFactory.createType(returnTypeField.getText()).validateElement("Invalid return type")
|
||||||
|
if (receiverTypeCheckBox.isSelected()) {
|
||||||
|
psiFactory.createType(receiverTypeField.getText()).validateElement("Invalid receiver type")
|
||||||
|
}
|
||||||
|
getDefaultReceiverValue()?.validateElement("Invalid default receiver value")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun doAction() {
|
||||||
|
val descriptor = (methodDescriptor as? JetMutableMethodDescriptor)?.original ?: methodDescriptor
|
||||||
|
|
||||||
|
val receiver = if (receiverTypeCheckBox.isSelected()) {
|
||||||
|
descriptor.receiver ?: JetParameterInfo(callableDescriptor = descriptor.baseDescriptor,
|
||||||
|
name = "receiver",
|
||||||
|
defaultValueForCall = getDefaultReceiverValue())
|
||||||
|
} else null
|
||||||
|
receiver?.currentTypeText = receiverTypeField.getText()
|
||||||
|
val changeInfo = JetChangeInfo(descriptor,
|
||||||
|
nameField.getText(),
|
||||||
|
null,
|
||||||
|
returnTypeField.getText(),
|
||||||
|
visibilityCombo.getSelectedItem() as Visibility,
|
||||||
|
emptyList(),
|
||||||
|
receiver,
|
||||||
|
descriptor.getMethod())
|
||||||
|
|
||||||
|
invokeRefactoring(JetChangeSignatureProcessor(myProject, changeInfo, commandName ?: getTitle()))
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun createProcessorForSilentRefactoring(
|
||||||
|
project: Project,
|
||||||
|
commandName: String,
|
||||||
|
descriptor: JetMethodDescriptor
|
||||||
|
): BaseRefactoringProcessor {
|
||||||
|
val originalDescriptor = (descriptor as? JetMutableMethodDescriptor)?.original ?: descriptor
|
||||||
|
val changeInfo = JetChangeInfo(methodDescriptor = originalDescriptor, context = originalDescriptor.getMethod())
|
||||||
|
changeInfo.setNewName(descriptor.getName())
|
||||||
|
changeInfo.receiverParameterInfo = descriptor.receiver
|
||||||
|
return JetChangeSignatureProcessor(project, changeInfo, commandName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+49
-29
@@ -23,11 +23,15 @@ import com.intellij.psi.PsiElement
|
|||||||
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler
|
import com.intellij.refactoring.changeSignature.ChangeSignatureHandler
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.refactoring.CallableRefactoring
|
import org.jetbrains.kotlin.idea.refactoring.CallableRefactoring
|
||||||
|
import org.jetbrains.kotlin.psi.JetClass
|
||||||
|
import org.jetbrains.kotlin.psi.JetFunction
|
||||||
|
import org.jetbrains.kotlin.psi.JetProperty
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||||
|
|
||||||
@@ -50,55 +54,64 @@ fun JetMethodDescriptor.modify(action: (JetMutableMethodDescriptor) -> Unit): Je
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun runChangeSignature(project: Project,
|
public fun runChangeSignature(project: Project,
|
||||||
functionDescriptor: FunctionDescriptor,
|
callableDescriptor: CallableDescriptor,
|
||||||
configuration: JetChangeSignatureConfiguration,
|
configuration: JetChangeSignatureConfiguration,
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
defaultValueContext: PsiElement,
|
defaultValueContext: PsiElement,
|
||||||
commandName: String? = null): Boolean {
|
commandName: String? = null): Boolean {
|
||||||
return JetChangeSignature(project, functionDescriptor, configuration, bindingContext, defaultValueContext, commandName).run()
|
return JetChangeSignature(project, callableDescriptor, configuration, bindingContext, defaultValueContext, commandName).run()
|
||||||
}
|
}
|
||||||
|
|
||||||
public class JetChangeSignature(project: Project,
|
public class JetChangeSignature(project: Project,
|
||||||
functionDescriptor: FunctionDescriptor,
|
callableDescriptor: CallableDescriptor,
|
||||||
val configuration: JetChangeSignatureConfiguration,
|
val configuration: JetChangeSignatureConfiguration,
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
val defaultValueContext: PsiElement,
|
val defaultValueContext: PsiElement,
|
||||||
commandName: String?): CallableRefactoring<FunctionDescriptor>(project, functionDescriptor, bindingContext, commandName) {
|
commandName: String?): CallableRefactoring<CallableDescriptor>(project, callableDescriptor, bindingContext, commandName) {
|
||||||
|
|
||||||
private val LOG = Logger.getInstance(javaClass<JetChangeSignature>())
|
private val LOG = Logger.getInstance(javaClass<JetChangeSignature>())
|
||||||
|
|
||||||
override fun forcePerformForSelectedFunctionOnly() = configuration.forcePerformForSelectedFunctionOnly()
|
override fun forcePerformForSelectedFunctionOnly() = configuration.forcePerformForSelectedFunctionOnly()
|
||||||
|
|
||||||
override fun performRefactoring(descriptorsForChange: Collection<CallableDescriptor>) {
|
private fun runSilentRefactoring(descriptor: JetMethodDescriptor) {
|
||||||
assert (descriptorsForChange.all { it is FunctionDescriptor }) {
|
val commandName = commandName ?: ChangeSignatureHandler.REFACTORING_NAME
|
||||||
"Function descriptors expected: " + descriptorsForChange.joinToString(separator = "\n")
|
val processor = when (descriptor.baseDeclaration) {
|
||||||
|
is JetFunction, is JetClass -> {
|
||||||
|
JetChangeSignatureDialog.createRefactoringProcessorForSilentChangeSignature(project, commandName, descriptor, defaultValueContext)
|
||||||
|
}
|
||||||
|
is JetProperty -> {
|
||||||
|
JetChangePropertySignatureDialog.createProcessorForSilentRefactoring(project, commandName, descriptor)
|
||||||
|
}
|
||||||
|
else -> throw AssertionError("Unexpected declaration: ${descriptor.baseDeclaration.getElementTextWithContext()}")
|
||||||
|
}
|
||||||
|
processor.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runInteractiveRefactoring(descriptor: JetMethodDescriptor) {
|
||||||
|
val dialog = when (descriptor.baseDeclaration) {
|
||||||
|
is JetFunction, is JetClass -> JetChangeSignatureDialog(project, descriptor, defaultValueContext, commandName)
|
||||||
|
is JetProperty -> JetChangePropertySignatureDialog(project, descriptor, commandName)
|
||||||
|
else -> throw AssertionError("Unexpected declaration: ${descriptor.baseDeclaration.getElementTextWithContext()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@suppress("UNCHECKED_CAST")
|
dialog.show()
|
||||||
val adjustedDescriptor = adjustDescriptor(descriptorsForChange as Collection<FunctionDescriptor>)
|
}
|
||||||
if (adjustedDescriptor == null) return
|
|
||||||
|
|
||||||
val affectedFunctions = adjustedDescriptor.affectedFunctions.map { it.getElement() }.filterNotNull()
|
override fun performRefactoring(descriptorsForChange: Collection<CallableDescriptor>) {
|
||||||
|
val adjustedDescriptor = adjustDescriptor(descriptorsForChange) ?: return
|
||||||
|
|
||||||
|
val affectedFunctions = adjustedDescriptor.affectedCallables.map { it.getElement() }.filterNotNull()
|
||||||
if (affectedFunctions.any { !checkModifiable(it) }) return
|
if (affectedFunctions.any { !checkModifiable(it) }) return
|
||||||
|
|
||||||
if (configuration.performSilently(affectedFunctions)
|
if (configuration.performSilently(affectedFunctions) || ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
||||||
|| ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
runSilentRefactoring(adjustedDescriptor)
|
||||||
JetChangeSignatureDialog.createRefactoringProcessorForSilentChangeSignature(
|
|
||||||
project,
|
|
||||||
commandName ?: ChangeSignatureHandler.REFACTORING_NAME,
|
|
||||||
adjustedDescriptor,
|
|
||||||
defaultValueContext
|
|
||||||
).run()
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val dialog = JetChangeSignatureDialog(project, adjustedDescriptor, defaultValueContext, commandName)
|
runInteractiveRefactoring(adjustedDescriptor)
|
||||||
|
|
||||||
dialog.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun adjustDescriptor(descriptorsForSignatureChange: Collection<FunctionDescriptor>): JetMethodDescriptor? {
|
fun adjustDescriptor(descriptorsForSignatureChange: Collection<CallableDescriptor>): JetMethodDescriptor? {
|
||||||
val baseDescriptor = preferContainedInClass(descriptorsForSignatureChange)
|
val baseDescriptor = preferContainedInClass(descriptorsForSignatureChange)
|
||||||
val functionDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, baseDescriptor)
|
val functionDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, baseDescriptor)
|
||||||
if (functionDeclaration == null) {
|
if (functionDeclaration == null) {
|
||||||
@@ -114,7 +127,7 @@ public class JetChangeSignature(project: Project,
|
|||||||
return configuration.configure(originalDescriptor, bindingContext)
|
return configuration.configure(originalDescriptor, bindingContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun preferContainedInClass(descriptorsForSignatureChange: Collection<FunctionDescriptor>): FunctionDescriptor {
|
private fun preferContainedInClass(descriptorsForSignatureChange: Collection<CallableDescriptor>): CallableDescriptor {
|
||||||
for (descriptor in descriptorsForSignatureChange) {
|
for (descriptor in descriptorsForSignatureChange) {
|
||||||
val containingDeclaration = descriptor.getContainingDeclaration()
|
val containingDeclaration = descriptor.getContainingDeclaration()
|
||||||
if (containingDeclaration is ClassDescriptor && containingDeclaration.getKind() != ClassKind.INTERFACE) {
|
if (containingDeclaration is ClassDescriptor && containingDeclaration.getKind() != ClassKind.INTERFACE) {
|
||||||
@@ -127,15 +140,22 @@ public class JetChangeSignature(project: Project,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestOnly public fun createChangeInfo(project: Project,
|
TestOnly public fun createChangeInfo(project: Project,
|
||||||
functionDescriptor: FunctionDescriptor,
|
callableDescriptor: CallableDescriptor,
|
||||||
configuration: JetChangeSignatureConfiguration,
|
configuration: JetChangeSignatureConfiguration,
|
||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
defaultValueContext: PsiElement): JetChangeInfo? {
|
defaultValueContext: PsiElement): JetChangeInfo? {
|
||||||
val jetChangeSignature = JetChangeSignature(project, functionDescriptor, configuration, bindingContext, defaultValueContext, null)
|
val jetChangeSignature = JetChangeSignature(project, callableDescriptor, configuration, bindingContext, defaultValueContext, null)
|
||||||
val declarations = OverrideResolver.getDeepestSuperDeclarations(functionDescriptor)
|
val declarations = if (callableDescriptor is CallableMemberDescriptor) {
|
||||||
|
OverrideResolver.getDeepestSuperDeclarations(callableDescriptor)
|
||||||
|
} else listOf(callableDescriptor)
|
||||||
|
|
||||||
val adjustedDescriptor = jetChangeSignature.adjustDescriptor(declarations) ?: return null
|
val adjustedDescriptor = jetChangeSignature.adjustDescriptor(declarations) ?: return null
|
||||||
|
|
||||||
val processor = JetChangeSignatureDialog.createRefactoringProcessorForSilentChangeSignature(project, ChangeSignatureHandler.REFACTORING_NAME, adjustedDescriptor, defaultValueContext) as JetChangeSignatureProcessor
|
val processor = JetChangeSignatureDialog.createRefactoringProcessorForSilentChangeSignature(
|
||||||
|
project,
|
||||||
|
ChangeSignatureHandler.REFACTORING_NAME,
|
||||||
|
adjustedDescriptor,
|
||||||
|
defaultValueContext
|
||||||
|
) as JetChangeSignatureProcessor
|
||||||
return processor.getChangeInfo()
|
return processor.getChangeInfo()
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-24
@@ -23,6 +23,8 @@ import com.intellij.refactoring.changeSignature.OverriderUsageInfo
|
|||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||||
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
@@ -30,10 +32,14 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
|||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.core.CollectingNameValidator
|
import org.jetbrains.kotlin.idea.core.CollectingNameValidator
|
||||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetCallableDefinitionUsage
|
||||||
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||||
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.JetCallableDeclaration
|
||||||
import org.jetbrains.kotlin.psi.JetClass
|
import org.jetbrains.kotlin.psi.JetClass
|
||||||
import org.jetbrains.kotlin.psi.JetFunction
|
import org.jetbrains.kotlin.psi.JetFunction
|
||||||
|
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
@@ -41,9 +47,9 @@ import java.util.HashSet
|
|||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
public class JetChangeSignatureData(
|
public class JetChangeSignatureData(
|
||||||
override val baseDescriptor: FunctionDescriptor,
|
override val baseDescriptor: CallableDescriptor,
|
||||||
override val baseDeclaration: PsiElement,
|
override val baseDeclaration: PsiElement,
|
||||||
private val descriptorsForSignatureChange: Collection<FunctionDescriptor>
|
private val descriptorsForSignatureChange: Collection<CallableDescriptor>
|
||||||
) : JetMethodDescriptor {
|
) : JetMethodDescriptor {
|
||||||
private val parameters: List<JetParameterInfo>
|
private val parameters: List<JetParameterInfo>
|
||||||
override val receiver: JetParameterInfo?
|
override val receiver: JetParameterInfo?
|
||||||
@@ -60,7 +66,7 @@ public class JetChangeSignatureData(
|
|||||||
.mapTo(receiver?.let{ arrayListOf(it) } ?: arrayListOf()) { parameterDescriptor ->
|
.mapTo(receiver?.let{ arrayListOf(it) } ?: arrayListOf()) { parameterDescriptor ->
|
||||||
val jetParameter = valueParameters?.get(parameterDescriptor.getIndex())
|
val jetParameter = valueParameters?.get(parameterDescriptor.getIndex())
|
||||||
JetParameterInfo(
|
JetParameterInfo(
|
||||||
functionDescriptor = baseDescriptor,
|
callableDescriptor = baseDescriptor,
|
||||||
originalIndex = parameterDescriptor.getIndex(),
|
originalIndex = parameterDescriptor.getIndex(),
|
||||||
name = parameterDescriptor.getName().asString(),
|
name = parameterDescriptor.getName().asString(),
|
||||||
type = parameterDescriptor.getType(),
|
type = parameterDescriptor.getType(),
|
||||||
@@ -72,8 +78,8 @@ public class JetChangeSignatureData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createReceiverInfoIfNeeded(): JetParameterInfo? {
|
private fun createReceiverInfoIfNeeded(): JetParameterInfo? {
|
||||||
val function = baseDeclaration as? JetFunction ?: return null
|
val callable = baseDeclaration as? JetCallableDeclaration ?: return null
|
||||||
val bodyScope = function.getBodyExpression()?.let { it.analyze()[BindingContext.RESOLUTION_SCOPE, it] }
|
val bodyScope = (callable as? JetFunction)?.getBodyExpression()?.let { it.analyze()[BindingContext.RESOLUTION_SCOPE, it] }
|
||||||
val paramNames = baseDescriptor.getValueParameters().map { it.getName().asString() }
|
val paramNames = baseDescriptor.getValueParameters().map { it.getName().asString() }
|
||||||
val validator = bodyScope?.let { bodyScope ->
|
val validator = bodyScope?.let { bodyScope ->
|
||||||
CollectingNameValidator(paramNames) {
|
CollectingNameValidator(paramNames) {
|
||||||
@@ -83,34 +89,37 @@ public class JetChangeSignatureData(
|
|||||||
} ?: CollectingNameValidator(paramNames)
|
} ?: CollectingNameValidator(paramNames)
|
||||||
val receiverType = baseDescriptor.getExtensionReceiverParameter()?.getType() ?: return null
|
val receiverType = baseDescriptor.getExtensionReceiverParameter()?.getType() ?: return null
|
||||||
val receiverName = KotlinNameSuggester.suggestNamesByType(receiverType, validator, "receiver").first()
|
val receiverName = KotlinNameSuggester.suggestNamesByType(receiverType, validator, "receiver").first()
|
||||||
return JetParameterInfo(functionDescriptor = baseDescriptor, name = receiverName, type = receiverType)
|
return JetParameterInfo(callableDescriptor = baseDescriptor, name = receiverName, type = receiverType)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val primaryFunctions: Collection<JetFunctionDefinitionUsage<PsiElement>> by Delegates.lazy {
|
override val primaryCallables: Collection<JetCallableDefinitionUsage<PsiElement>> by Delegates.lazy {
|
||||||
descriptorsForSignatureChange.map {
|
descriptorsForSignatureChange.map {
|
||||||
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(baseDeclaration.getProject(), it)
|
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(baseDeclaration.getProject(), it)
|
||||||
assert(declaration != null) { "No declaration found for " + baseDescriptor }
|
assert(declaration != null) { "No declaration found for " + baseDescriptor }
|
||||||
JetFunctionDefinitionUsage<PsiElement>(declaration, it, null, null)
|
JetCallableDefinitionUsage<PsiElement>(declaration, it, null, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val originalPrimaryFunction: JetFunctionDefinitionUsage<PsiElement> by Delegates.lazy {
|
override val originalPrimaryCallable: JetCallableDefinitionUsage<PsiElement> by Delegates.lazy {
|
||||||
primaryFunctions.first { it.getDeclaration() == baseDeclaration }
|
primaryCallables.first { it.getDeclaration() == baseDeclaration }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val affectedFunctions: Collection<UsageInfo> by Delegates.lazy {
|
override val affectedCallables: Collection<UsageInfo> by Delegates.lazy {
|
||||||
primaryFunctions + primaryFunctions.flatMapTo(HashSet<UsageInfo>()) { primaryFunction ->
|
primaryCallables + primaryCallables.flatMapTo(HashSet<UsageInfo>()) { primaryFunction ->
|
||||||
val primaryDeclaration = primaryFunction.getDeclaration() as? JetFunction
|
val primaryDeclaration = primaryFunction.getDeclaration() as? JetCallableDeclaration
|
||||||
val lightMethod = primaryDeclaration?.let { LightClassUtil.getLightClassMethod(it) }
|
val lightMethods = primaryDeclaration?.toLightMethods() ?: Collections.emptyList()
|
||||||
val overrides = lightMethod?.let { OverridingMethodsSearch.search(it).findAll() } ?: Collections.emptyList()
|
lightMethods.flatMap { baseMethod ->
|
||||||
overrides.map { method ->
|
OverridingMethodsSearch
|
||||||
if (method is KotlinLightMethod) {
|
.search(baseMethod)
|
||||||
val overridingDeclaration = method.getOrigin()
|
.map { overridingMethod ->
|
||||||
val overridingDescriptor = overridingDeclaration?.resolveToDescriptor() as FunctionDescriptor
|
if (overridingMethod is KotlinLightMethod) {
|
||||||
JetFunctionDefinitionUsage<PsiElement>(overridingDeclaration, overridingDescriptor, primaryFunction, null)
|
val overridingDeclaration = overridingMethod.namedUnwrappedElement as JetNamedDeclaration
|
||||||
}
|
val overridingDescriptor = overridingDeclaration.resolveToDescriptor() as CallableDescriptor
|
||||||
else OverriderUsageInfo(method, lightMethod, true, true, true)
|
JetCallableDefinitionUsage<PsiElement>(overridingDeclaration, overridingDescriptor, primaryFunction, null)
|
||||||
}.filterNotNullTo(HashSet<UsageInfo>())
|
}
|
||||||
|
else OverriderUsageInfo(overridingMethod, baseMethod, true, true, true)
|
||||||
|
}.filterNotNullTo(HashSet<UsageInfo>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -416,7 +416,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
|||||||
getMethodName(),
|
getMethodName(),
|
||||||
myDefaultValueContext
|
myDefaultValueContext
|
||||||
);
|
);
|
||||||
return changeInfo.getNewSignature(getMethodDescriptor().getOriginalPrimaryFunction());
|
return changeInfo.getNewSignature(getMethodDescriptor().getOriginalPrimaryCallable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+33
-33
@@ -34,10 +34,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.TestOnly;
|
import org.jetbrains.annotations.TestOnly;
|
||||||
import org.jetbrains.kotlin.asJava.AsJavaPackage;
|
import org.jetbrains.kotlin.asJava.AsJavaPackage;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils;
|
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils;
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde;
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde;
|
||||||
@@ -57,44 +54,44 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static PsiElement findTargetForRefactoring(@NotNull PsiElement element) {
|
public static PsiElement findTargetForRefactoring(@NotNull PsiElement element) {
|
||||||
if (PsiTreeUtil.getParentOfType(element, JetParameterList.class) != null) {
|
if (PsiTreeUtil.getParentOfType(element, JetParameterList.class) != null) {
|
||||||
return PsiTreeUtil.getParentOfType(element, JetFunction.class, JetClass.class);
|
return PsiTreeUtil.getParentOfType(element, JetFunction.class, JetProperty.class, JetClass.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
JetTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, JetTypeParameterList.class);
|
JetTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, JetTypeParameterList.class);
|
||||||
if (typeParameterList != null) {
|
if (typeParameterList != null) {
|
||||||
return PsiTreeUtil.getParentOfType(typeParameterList, JetFunction.class, JetClass.class);
|
return PsiTreeUtil.getParentOfType(typeParameterList, JetFunction.class, JetProperty.class, JetClass.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
PsiElement elementParent = element.getParent();
|
PsiElement elementParent = element.getParent();
|
||||||
if (elementParent instanceof JetNamedFunction && ((JetNamedFunction) elementParent).getNameIdentifier() == element) {
|
if ((elementParent instanceof JetNamedFunction || elementParent instanceof JetClass || elementParent instanceof JetProperty)
|
||||||
return elementParent;
|
&& ((JetNamedDeclaration) elementParent).getNameIdentifier() == element) return elementParent;
|
||||||
}
|
|
||||||
if (elementParent instanceof JetClass && ((JetClass) elementParent).getNameIdentifier() == element) {
|
|
||||||
return elementParent;
|
|
||||||
}
|
|
||||||
if (elementParent instanceof JetSecondaryConstructor &&
|
|
||||||
((JetSecondaryConstructor) elementParent).getConstructorKeyword() == element) {
|
|
||||||
return elementParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (elementParent instanceof JetSecondaryConstructor &&
|
||||||
|
((JetSecondaryConstructor) elementParent).getConstructorKeyword() == element) return elementParent;
|
||||||
|
|
||||||
|
JetExpression calleeExpr;
|
||||||
JetCallElement call = PsiTreeUtil.getParentOfType(element,
|
JetCallElement call = PsiTreeUtil.getParentOfType(element,
|
||||||
JetCallExpression.class,
|
JetCallExpression.class,
|
||||||
JetDelegatorToSuperCall.class,
|
JetDelegatorToSuperCall.class,
|
||||||
JetConstructorDelegationCall.class);
|
JetConstructorDelegationCall.class);
|
||||||
if (call == null) return null;
|
if (call != null) {
|
||||||
|
calleeExpr = call.getCalleeExpression();
|
||||||
JetExpression receiverExpr = call.getCalleeExpression();
|
|
||||||
if (receiverExpr instanceof JetConstructorCalleeExpression) {
|
|
||||||
receiverExpr = ((JetConstructorCalleeExpression) receiverExpr).getConstructorReferenceExpression();
|
|
||||||
}
|
}
|
||||||
if (receiverExpr instanceof JetSimpleNameExpression || receiverExpr instanceof JetConstructorDelegationReferenceExpression) {
|
else {
|
||||||
|
calleeExpr = PsiTreeUtil.getParentOfType(element, JetSimpleNameExpression.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calleeExpr instanceof JetConstructorCalleeExpression) {
|
||||||
|
calleeExpr = ((JetConstructorCalleeExpression) calleeExpr).getConstructorReferenceExpression();
|
||||||
|
}
|
||||||
|
if (calleeExpr instanceof JetSimpleNameExpression || calleeExpr instanceof JetConstructorDelegationReferenceExpression) {
|
||||||
JetElement jetElement = PsiTreeUtil.getParentOfType(element, JetElement.class);
|
JetElement jetElement = PsiTreeUtil.getParentOfType(element, JetElement.class);
|
||||||
if (jetElement == null) return null;
|
if (jetElement == null) return null;
|
||||||
|
|
||||||
BindingContext bindingContext = ResolvePackage.analyze(jetElement, BodyResolveMode.FULL);
|
BindingContext bindingContext = ResolvePackage.analyze(jetElement, BodyResolveMode.FULL);
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) receiverExpr);
|
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetReferenceExpression) calleeExpr);
|
||||||
|
|
||||||
if (descriptor instanceof ClassDescriptor || descriptor instanceof FunctionDescriptor) return receiverExpr;
|
if (descriptor instanceof ClassDescriptor || descriptor instanceof CallableDescriptor) return calleeExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -107,20 +104,20 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
@Nullable Editor editor
|
@Nullable Editor editor
|
||||||
) {
|
) {
|
||||||
BindingContext bindingContext = ResolvePackage.analyze(element, BodyResolveMode.FULL);
|
BindingContext bindingContext = ResolvePackage.analyze(element, BodyResolveMode.FULL);
|
||||||
|
|
||||||
FunctionDescriptor functionDescriptor = findDescriptor(element, project, editor, bindingContext);
|
CallableDescriptor callableDescriptor = findDescriptor(element, project, editor, bindingContext);
|
||||||
if (functionDescriptor == null) {
|
if (callableDescriptor == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionDescriptor instanceof JavaCallableMemberDescriptor) {
|
if (callableDescriptor instanceof JavaCallableMemberDescriptor) {
|
||||||
PsiElement declaration = DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(project, functionDescriptor);
|
PsiElement declaration = DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(project, callableDescriptor);
|
||||||
assert declaration instanceof PsiMethod : "PsiMethod expected: " + functionDescriptor;
|
assert declaration instanceof PsiMethod : "PsiMethod expected: " + callableDescriptor;
|
||||||
ChangeSignatureUtil.invokeChangeSignatureOn((PsiMethod) declaration, project);
|
ChangeSignatureUtil.invokeChangeSignatureOn((PsiMethod) declaration, project);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TasksPackage.isDynamic(functionDescriptor)) {
|
if (TasksPackage.isDynamic(callableDescriptor)) {
|
||||||
if (editor != null) {
|
if (editor != null) {
|
||||||
CodeInsightUtils.showErrorHint(
|
CodeInsightUtils.showErrorHint(
|
||||||
project,
|
project,
|
||||||
@@ -133,7 +130,7 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
runChangeSignature(project, functionDescriptor, emptyConfiguration(), bindingContext, context, null);
|
runChangeSignature(project, callableDescriptor, emptyConfiguration(), bindingContext, context, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOnly
|
@TestOnly
|
||||||
@@ -208,7 +205,7 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static FunctionDescriptor findDescriptor(
|
public static CallableDescriptor findDescriptor(
|
||||||
@NotNull PsiElement element,
|
@NotNull PsiElement element,
|
||||||
@NotNull Project project,
|
@NotNull Project project,
|
||||||
@Nullable Editor editor,
|
@Nullable Editor editor,
|
||||||
@@ -244,6 +241,9 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
|||||||
|
|
||||||
return (FunctionDescriptor) descriptor;
|
return (FunctionDescriptor) descriptor;
|
||||||
}
|
}
|
||||||
|
else if (descriptor instanceof PropertyDescriptor) {
|
||||||
|
return (PropertyDescriptor) descriptor;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
String message = RefactoringBundle.getCannotRefactorMessage(JetRefactoringBundle.message(
|
String message = RefactoringBundle.getCannotRefactorMessage(JetRefactoringBundle.message(
|
||||||
"error.wrong.caret.position.function.or.constructor.name"));
|
"error.wrong.caret.position.function.or.constructor.name"));
|
||||||
|
|||||||
+11
-7
@@ -21,7 +21,10 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.openapi.util.Ref;
|
import com.intellij.openapi.util.Ref;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.refactoring.RefactoringBundle;
|
import com.intellij.refactoring.RefactoringBundle;
|
||||||
import com.intellij.refactoring.changeSignature.*;
|
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase;
|
||||||
|
import com.intellij.refactoring.changeSignature.ChangeSignatureUsageProcessor;
|
||||||
|
import com.intellij.refactoring.changeSignature.JavaChangeInfo;
|
||||||
|
import com.intellij.refactoring.changeSignature.JavaChangeSignatureUsageProcessor;
|
||||||
import com.intellij.refactoring.rename.RenameUtil;
|
import com.intellij.refactoring.rename.RenameUtil;
|
||||||
import com.intellij.refactoring.ui.ConflictsDialog;
|
import com.intellij.refactoring.ui.ConflictsDialog;
|
||||||
import com.intellij.usageView.UsageInfo;
|
import com.intellij.usageView.UsageInfo;
|
||||||
@@ -29,8 +32,6 @@ import com.intellij.usageView.UsageViewDescriptor;
|
|||||||
import com.intellij.util.containers.HashSet;
|
import com.intellij.util.containers.HashSet;
|
||||||
import com.intellij.util.containers.MultiMap;
|
import com.intellij.util.containers.MultiMap;
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
import kotlin.Pair;
|
|
||||||
import kotlin.jvm.functions.Function1;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetUsageInfo;
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetUsageInfo;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinWrapperForJavaUsageInfos;
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinWrapperForJavaUsageInfos;
|
||||||
@@ -62,10 +63,13 @@ public class JetChangeSignatureProcessor extends ChangeSignatureProcessorBase {
|
|||||||
protected UsageInfo[] findUsages() {
|
protected UsageInfo[] findUsages() {
|
||||||
List<UsageInfo> allUsages = new ArrayList<UsageInfo>();
|
List<UsageInfo> allUsages = new ArrayList<UsageInfo>();
|
||||||
|
|
||||||
JavaChangeInfo javaChangeInfo = getChangeInfo().getOrCreateJavaChangeInfo();
|
List<JavaChangeInfo> javaChangeInfos = getChangeInfo().getOrCreateJavaChangeInfos();
|
||||||
if (javaChangeInfo != null) {
|
if (javaChangeInfos != null) {
|
||||||
UsageInfo[] javaUsages = new JavaChangeSignatureUsageProcessor().findUsages(javaChangeInfo);
|
JavaChangeSignatureUsageProcessor javaProcessor = new JavaChangeSignatureUsageProcessor();
|
||||||
allUsages.add(new KotlinWrapperForJavaUsageInfos(javaUsages, getChangeInfo().getMethod()));
|
for (JavaChangeInfo javaChangeInfo : javaChangeInfos) {
|
||||||
|
UsageInfo[] javaUsages = javaProcessor.findUsages(javaChangeInfo);
|
||||||
|
allUsages.add(new KotlinWrapperForJavaUsageInfos(javaChangeInfo, javaUsages, getChangeInfo().getMethod()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
KotlinPackage.filterIsInstanceTo(super.findUsages(), allUsages, JetUsageInfo.class);
|
KotlinPackage.filterIsInstanceTo(super.findUsages(), allUsages, JetUsageInfo.class);
|
||||||
|
|
||||||
|
|||||||
+54
-48
@@ -21,9 +21,9 @@ import com.intellij.openapi.project.Project;
|
|||||||
import com.intellij.openapi.util.Ref;
|
import com.intellij.openapi.util.Ref;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.GlobalSearchScope;
|
||||||
import com.intellij.psi.search.SearchScope;
|
import com.intellij.psi.search.SearchScope;
|
||||||
|
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.refactoring.changeSignature.ChangeInfo;
|
import com.intellij.refactoring.changeSignature.ChangeInfo;
|
||||||
@@ -40,7 +40,6 @@ import com.intellij.util.Function;
|
|||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import com.intellij.util.containers.HashSet;
|
import com.intellij.util.containers.HashSet;
|
||||||
import com.intellij.util.containers.MultiMap;
|
import com.intellij.util.containers.MultiMap;
|
||||||
import jet.runtime.typeinfo.JetValueParameter;
|
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import kotlin.jvm.functions.Function1;
|
import kotlin.jvm.functions.Function1;
|
||||||
@@ -56,13 +55,13 @@ import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde;
|
|||||||
import org.jetbrains.kotlin.idea.codeInsight.JetFileReferencesResolver;
|
import org.jetbrains.kotlin.idea.codeInsight.JetFileReferencesResolver;
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.RefactoringPackage;
|
import org.jetbrains.kotlin.idea.core.refactoring.RefactoringPackage;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.*;
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.*;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.rename.UnresolvableConventionViolationUsageInfo;
|
|
||||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference;
|
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference;
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchPackage;
|
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchPackage;
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName;
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName;
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||||
import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersPackage;
|
import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersPackage;
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -72,7 +71,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||||
@@ -80,10 +78,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver;
|
|||||||
import org.jetbrains.kotlin.types.JetType;
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
import org.jetbrains.kotlin.types.TypeUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsageProcessor {
|
public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsageProcessor {
|
||||||
@Override
|
@Override
|
||||||
@@ -104,8 +99,8 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
|
|
||||||
private static void findAllMethodUsages(JetChangeInfo changeInfo, Set<UsageInfo> result) {
|
private static void findAllMethodUsages(JetChangeInfo changeInfo, Set<UsageInfo> result) {
|
||||||
for (UsageInfo functionUsageInfo : ChangeSignaturePackage.getAffectedFunctions(changeInfo)) {
|
for (UsageInfo functionUsageInfo : ChangeSignaturePackage.getAffectedFunctions(changeInfo)) {
|
||||||
if (functionUsageInfo instanceof JetFunctionDefinitionUsage) {
|
if (functionUsageInfo instanceof JetCallableDefinitionUsage) {
|
||||||
findOneMethodUsages((JetFunctionDefinitionUsage) functionUsageInfo, changeInfo, result);
|
findOneMethodUsages((JetCallableDefinitionUsage) functionUsageInfo, changeInfo, result);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result.add(functionUsageInfo);
|
result.add(functionUsageInfo);
|
||||||
@@ -123,7 +118,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
JetCallElement callElement = PsiTreeUtil.getParentOfType(element, JetCallElement.class);
|
JetCallElement callElement = PsiTreeUtil.getParentOfType(element, JetCallElement.class);
|
||||||
JetExpression calleeExpression = callElement != null ? callElement.getCalleeExpression() : null;
|
JetExpression calleeExpression = callElement != null ? callElement.getCalleeExpression() : null;
|
||||||
if (calleeExpression != null && PsiTreeUtil.isAncestor(calleeExpression, element, false)) {
|
if (calleeExpression != null && PsiTreeUtil.isAncestor(calleeExpression, element, false)) {
|
||||||
result.add(new JetFunctionCallUsage(callElement, changeInfo.getMethodDescriptor().getOriginalPrimaryFunction()));
|
result.add(new JetFunctionCallUsage(callElement, changeInfo.getMethodDescriptor().getOriginalPrimaryCallable()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +126,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void findOneMethodUsages(
|
private static void findOneMethodUsages(
|
||||||
@NotNull JetFunctionDefinitionUsage<?> functionUsageInfo,
|
@NotNull JetCallableDefinitionUsage<?> functionUsageInfo,
|
||||||
final JetChangeInfo changeInfo,
|
final JetChangeInfo changeInfo,
|
||||||
final Set<UsageInfo> result
|
final Set<UsageInfo> result
|
||||||
) {
|
) {
|
||||||
@@ -160,6 +155,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
if (parent instanceof JetConstructorCalleeExpression && parent.getParent() instanceof JetDelegatorToSuperCall)
|
if (parent instanceof JetConstructorCalleeExpression && parent.getParent() instanceof JetDelegatorToSuperCall)
|
||||||
result.add(new JetFunctionCallUsage((JetDelegatorToSuperCall)parent.getParent(), functionUsageInfo));
|
result.add(new JetFunctionCallUsage((JetDelegatorToSuperCall)parent.getParent(), functionUsageInfo));
|
||||||
}
|
}
|
||||||
|
else if (element instanceof JetSimpleNameExpression && functionPsi instanceof JetProperty) {
|
||||||
|
result.add(new JetPropertyCallUsage((JetSimpleNameExpression) element));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,9 +166,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
if (oldName != null)
|
if (oldName != null)
|
||||||
TextOccurrencesUtil.findNonCodeUsages(functionPsi, oldName, true, true, changeInfo.getNewName(), result);
|
TextOccurrencesUtil.findNonCodeUsages(functionPsi, oldName, true, true, changeInfo.getNewName(), result);
|
||||||
|
|
||||||
List<JetParameter> oldParameters = functionPsi instanceof JetFunction
|
List<JetParameter> oldParameters = PsiUtilPackage.getValueParameters((JetNamedDeclaration) functionPsi);
|
||||||
? ((JetFunction) functionPsi).getValueParameters()
|
|
||||||
: ((JetClass) functionPsi).getPrimaryConstructorParameters();
|
|
||||||
|
|
||||||
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
||||||
|
|
||||||
@@ -221,7 +217,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void processInternalReferences(
|
private static void processInternalReferences(
|
||||||
JetFunctionDefinitionUsage functionUsageInfo,
|
JetCallableDefinitionUsage functionUsageInfo,
|
||||||
JetTreeVisitor<BindingContext> visitor
|
JetTreeVisitor<BindingContext> visitor
|
||||||
) {
|
) {
|
||||||
JetFunction jetFunction = (JetFunction) functionUsageInfo.getDeclaration();
|
JetFunction jetFunction = (JetFunction) functionUsageInfo.getDeclaration();
|
||||||
@@ -238,12 +234,12 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void findOriginalReceiversUsages(
|
private static void findOriginalReceiversUsages(
|
||||||
@NotNull final JetFunctionDefinitionUsage<?> functionUsageInfo,
|
@NotNull final JetCallableDefinitionUsage<?> functionUsageInfo,
|
||||||
@NotNull final Set<UsageInfo> result,
|
@NotNull final Set<UsageInfo> result,
|
||||||
@NotNull final JetChangeInfo changeInfo
|
@NotNull final JetChangeInfo changeInfo
|
||||||
) {
|
) {
|
||||||
final JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
final JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
||||||
final FunctionDescriptor functionDescriptor = functionUsageInfo.getOriginalFunctionDescriptor();
|
final CallableDescriptor callableDescriptor = functionUsageInfo.getOriginalCallableDescriptor();
|
||||||
processInternalReferences(
|
processInternalReferences(
|
||||||
functionUsageInfo,
|
functionUsageInfo,
|
||||||
new JetTreeVisitor<BindingContext>() {
|
new JetTreeVisitor<BindingContext>() {
|
||||||
@@ -254,7 +250,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
if (originalReceiverInfo != null && !changeInfo.hasParameter(originalReceiverInfo)) return;
|
if (originalReceiverInfo != null && !changeInfo.hasParameter(originalReceiverInfo)) return;
|
||||||
if (!(expression.getParent() instanceof JetThisExpression)) return;
|
if (!(expression.getParent() instanceof JetThisExpression)) return;
|
||||||
|
|
||||||
if (receiverDescriptor == functionDescriptor.getExtensionReceiverParameter()) {
|
if (receiverDescriptor == callableDescriptor.getExtensionReceiverParameter()) {
|
||||||
assert originalReceiverInfo != null : "No original receiver info provided: " + functionUsageInfo.getDeclaration().getText();
|
assert originalReceiverInfo != null : "No original receiver info provided: " + functionUsageInfo.getDeclaration().getText();
|
||||||
result.add(new JetParameterUsage(expression, originalReceiverInfo, functionUsageInfo));
|
result.add(new JetParameterUsage(expression, originalReceiverInfo, functionUsageInfo));
|
||||||
}
|
}
|
||||||
@@ -270,7 +266,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
@NotNull ThisReceiver receiverValue
|
@NotNull ThisReceiver receiverValue
|
||||||
) {
|
) {
|
||||||
DeclarationDescriptor targetDescriptor = receiverValue.getDeclarationDescriptor();
|
DeclarationDescriptor targetDescriptor = receiverValue.getDeclarationDescriptor();
|
||||||
if (targetDescriptor == functionDescriptor) {
|
if (targetDescriptor == callableDescriptor) {
|
||||||
assert originalReceiverInfo != null : "No original receiver info provided: " + functionUsageInfo.getDeclaration().getText();
|
assert originalReceiverInfo != null : "No original receiver info provided: " + functionUsageInfo.getDeclaration().getText();
|
||||||
result.add(new JetImplicitThisToParameterUsage(callElement, originalReceiverInfo, functionUsageInfo));
|
result.add(new JetImplicitThisToParameterUsage(callElement, originalReceiverInfo, functionUsageInfo));
|
||||||
}
|
}
|
||||||
@@ -407,7 +403,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
PsiElement function = info.getMethod();
|
PsiElement function = info.getMethod();
|
||||||
PsiElement element = function != null ? function : changeInfo.getContext();
|
PsiElement element = function != null ? function : changeInfo.getContext();
|
||||||
BindingContext bindingContext = ResolvePackage.analyze((JetElement) element, BodyResolveMode.FULL);
|
BindingContext bindingContext = ResolvePackage.analyze((JetElement) element, BodyResolveMode.FULL);
|
||||||
FunctionDescriptor oldDescriptor = ChangeSignaturePackage.getOriginalBaseFunctionDescriptor(changeInfo);
|
CallableDescriptor oldDescriptor = ChangeSignaturePackage.getOriginalBaseFunctionDescriptor(changeInfo);
|
||||||
DeclarationDescriptor containingDeclaration = oldDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = oldDescriptor.getContainingDeclaration();
|
||||||
|
|
||||||
JetScope parametersScope = null;
|
JetScope parametersScope = null;
|
||||||
@@ -416,17 +412,21 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
else if (function instanceof JetFunction)
|
else if (function instanceof JetFunction)
|
||||||
parametersScope = org.jetbrains.kotlin.idea.refactoring.RefactoringPackage.getBodyScope((JetFunction) function, bindingContext);
|
parametersScope = org.jetbrains.kotlin.idea.refactoring.RefactoringPackage.getBodyScope((JetFunction) function, bindingContext);
|
||||||
|
|
||||||
JetScope functionScope = org.jetbrains.kotlin.idea.refactoring.RefactoringPackage.getContainingScope(oldDescriptor, bindingContext);
|
JetScope callableScope = org.jetbrains.kotlin.idea.refactoring.RefactoringPackage.getContainingScope(oldDescriptor, bindingContext);
|
||||||
|
|
||||||
JetMethodDescriptor.Kind kind = ChangeSignaturePackage.getKind(changeInfo);
|
JetMethodDescriptor.Kind kind = ChangeSignaturePackage.getKind(changeInfo);
|
||||||
if (!kind.getIsConstructor() && functionScope != null && !info.getNewName().isEmpty()) {
|
if (!kind.getIsConstructor() && callableScope != null && !info.getNewName().isEmpty()) {
|
||||||
for (FunctionDescriptor conflict : functionScope.getFunctions(Name.identifier(info.getNewName()))) {
|
Name newName = Name.identifier(info.getNewName());
|
||||||
|
Collection<? extends CallableDescriptor> conflicts = oldDescriptor instanceof FunctionDescriptor
|
||||||
|
? callableScope.getFunctions(newName)
|
||||||
|
: callableScope.getProperties(newName);
|
||||||
|
for (CallableDescriptor conflict : conflicts) {
|
||||||
if (conflict == oldDescriptor) continue;
|
if (conflict == oldDescriptor) continue;
|
||||||
|
|
||||||
PsiElement conflictElement = DescriptorToSourceUtils.descriptorToDeclaration(conflict);
|
PsiElement conflictElement = DescriptorToSourceUtils.descriptorToDeclaration(conflict);
|
||||||
if (conflictElement == changeInfo.getMethod()) continue;
|
if (conflictElement == changeInfo.getMethod()) continue;
|
||||||
|
|
||||||
if (getFunctionParameterTypes(conflict).equals(getFunctionParameterTypes(oldDescriptor))) {
|
if (getCallableParameterTypes(conflict).equals(getCallableParameterTypes(oldDescriptor))) {
|
||||||
result.putValue(conflictElement, "Function already exists: '" + DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(conflict) + "'");
|
result.putValue(conflictElement, "Function already exists: '" + DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(conflict) + "'");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -464,7 +464,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
|
|
||||||
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
||||||
JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
||||||
if (function instanceof JetNamedFunction && newReceiverInfo != originalReceiverInfo) {
|
if (function instanceof JetCallableDeclaration && newReceiverInfo != originalReceiverInfo) {
|
||||||
findReceiverIntroducingConflicts(result, function, newReceiverInfo);
|
findReceiverIntroducingConflicts(result, function, newReceiverInfo);
|
||||||
findInternalExplicitReceiverConflicts(refUsages.get(), result, originalReceiverInfo);
|
findInternalExplicitReceiverConflicts(refUsages.get(), result, originalReceiverInfo);
|
||||||
findThisLabelConflicts((JetChangeInfo) info, refUsages, result, changeInfo, function);
|
findThisLabelConflicts((JetChangeInfo) info, refUsages, result, changeInfo, function);
|
||||||
@@ -525,10 +525,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
) {
|
) {
|
||||||
if (originalReceiverInfo == null) {
|
if (originalReceiverInfo == null) {
|
||||||
for (UsageInfo usageInfo : usages) {
|
for (UsageInfo usageInfo : usages) {
|
||||||
if (!(usageInfo instanceof JetFunctionCallUsage)) continue;
|
if (!(usageInfo instanceof JetFunctionCallUsage || usageInfo instanceof JetPropertyCallUsage)) continue;
|
||||||
|
|
||||||
JetFunctionCallUsage callUsage = (JetFunctionCallUsage) usageInfo;
|
JetElement callElement = (JetElement) usageInfo.getElement();
|
||||||
JetElement callElement = callUsage.getElement();
|
|
||||||
if (callElement == null) continue;
|
if (callElement == null) continue;
|
||||||
|
|
||||||
PsiElement parent = callElement.getParent();
|
PsiElement parent = callElement.getParent();
|
||||||
@@ -546,7 +545,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
PsiElement callable,
|
PsiElement callable,
|
||||||
JetParameterInfo newReceiverInfo
|
JetParameterInfo newReceiverInfo
|
||||||
) {
|
) {
|
||||||
if (newReceiverInfo != null && ((JetNamedFunction) callable).getBodyExpression() != null) {
|
if (newReceiverInfo != null && (callable instanceof JetNamedFunction) && ((JetNamedFunction) callable).getBodyExpression() != null) {
|
||||||
Map<JetReferenceExpression, BindingContext> noReceiverRefToContext = KotlinPackage.filter(
|
Map<JetReferenceExpression, BindingContext> noReceiverRefToContext = KotlinPackage.filter(
|
||||||
JetFileReferencesResolver.INSTANCE$.resolve((JetNamedFunction) callable, true, true),
|
JetFileReferencesResolver.INSTANCE$.resolve((JetNamedFunction) callable, true, true),
|
||||||
new Function1<Map.Entry<? extends JetReferenceExpression, ? extends BindingContext>, Boolean>() {
|
new Function1<Map.Entry<? extends JetReferenceExpression, ? extends BindingContext>, Boolean>() {
|
||||||
@@ -606,7 +605,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<JetType> getFunctionParameterTypes(FunctionDescriptor descriptor) {
|
private static List<JetType> getCallableParameterTypes(CallableDescriptor descriptor) {
|
||||||
return ContainerUtil.map(descriptor.getValueParameters(), new Function<ValueParameterDescriptor, JetType>() {
|
return ContainerUtil.map(descriptor.getValueParameters(), new Function<ValueParameterDescriptor, JetType>() {
|
||||||
@Override
|
@Override
|
||||||
public JetType fun(ValueParameterDescriptor descriptor) {
|
public JetType fun(ValueParameterDescriptor descriptor) {
|
||||||
@@ -710,26 +709,33 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
boolean isJavaMethodUsage = isJavaMethodUsage(usageInfo);
|
boolean isJavaMethodUsage = isJavaMethodUsage(usageInfo);
|
||||||
|
|
||||||
if (usageInfo instanceof KotlinWrapperForJavaUsageInfos) {
|
if (usageInfo instanceof KotlinWrapperForJavaUsageInfos) {
|
||||||
JavaChangeInfo javaChangeInfo = ((JetChangeInfo) changeInfo).getOrCreateJavaChangeInfo();
|
List<JavaChangeInfo> javaChangeInfos = ((JetChangeInfo) changeInfo).getOrCreateJavaChangeInfos();
|
||||||
assert javaChangeInfo != null : "JavaChangeInfo not found: " + method.getText();
|
assert javaChangeInfos != null : "JavaChangeInfo not found: " + method.getText();
|
||||||
UsageInfo[] javaUsageInfos = ((KotlinWrapperForJavaUsageInfos) usageInfo).getJavaUsageInfos();
|
|
||||||
|
KotlinWrapperForJavaUsageInfos wrapperForJavaUsageInfos = (KotlinWrapperForJavaUsageInfos) usageInfo;
|
||||||
|
UsageInfo[] javaUsageInfos = wrapperForJavaUsageInfos.getJavaUsageInfos();
|
||||||
ChangeSignatureUsageProcessor[] processors = ChangeSignatureUsageProcessor.EP_NAME.getExtensions();
|
ChangeSignatureUsageProcessor[] processors = ChangeSignatureUsageProcessor.EP_NAME.getExtensions();
|
||||||
|
|
||||||
NullabilityPropagator nullabilityPropagator = new NullabilityPropagator(javaChangeInfo.getMethod());
|
for (JavaChangeInfo javaChangeInfo : javaChangeInfos) {
|
||||||
|
// Match names so that getter/setter usages are not confused with each other
|
||||||
|
if (!javaChangeInfo.getOldName().equals(wrapperForJavaUsageInfos.getJavaChangeInfo().getOldName())) continue;
|
||||||
|
|
||||||
for (UsageInfo usage : javaUsageInfos) {
|
NullabilityPropagator nullabilityPropagator = new NullabilityPropagator(javaChangeInfo.getMethod());
|
||||||
if (usage instanceof OverriderUsageInfo && beforeMethodChange) continue;
|
|
||||||
for (ChangeSignatureUsageProcessor processor : processors) {
|
for (UsageInfo usage : javaUsageInfos) {
|
||||||
if (processor instanceof JetChangeSignatureUsageProcessor) continue;
|
if (usage instanceof OverriderUsageInfo && beforeMethodChange) continue;
|
||||||
if (usage instanceof OverriderUsageInfo) {
|
for (ChangeSignatureUsageProcessor processor : processors) {
|
||||||
processor.processUsage(javaChangeInfo, usage, true, javaUsageInfos);
|
if (processor instanceof JetChangeSignatureUsageProcessor) continue;
|
||||||
|
if (usage instanceof OverriderUsageInfo) {
|
||||||
|
processor.processUsage(javaChangeInfo, usage, true, javaUsageInfos);
|
||||||
|
}
|
||||||
|
if (processor.processUsage(javaChangeInfo, usage, beforeMethodChange, javaUsageInfos)) break;
|
||||||
}
|
}
|
||||||
if (processor.processUsage(javaChangeInfo, usage, beforeMethodChange, javaUsageInfos)) break;
|
if (usage instanceof OverriderUsageInfo) {
|
||||||
}
|
PsiMethod overridingMethod = ((OverriderUsageInfo) usage).getOverridingMethod();
|
||||||
if (usage instanceof OverriderUsageInfo) {
|
if (overridingMethod != null && !(overridingMethod instanceof KotlinLightMethod)) {
|
||||||
PsiMethod overridingMethod = ((OverriderUsageInfo)usage).getOverridingMethod();
|
nullabilityPropagator.processMethod(overridingMethod);
|
||||||
if (overridingMethod != null && !(overridingMethod instanceof KotlinLightMethod)) {
|
}
|
||||||
nullabilityPropagator.processMethod(overridingMethod);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -792,7 +798,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
if (!(changeInfo instanceof JetChangeInfo)) return false;
|
if (!(changeInfo instanceof JetChangeInfo)) return false;
|
||||||
|
|
||||||
JetChangeInfo jetChangeInfo = (JetChangeInfo) changeInfo;
|
JetChangeInfo jetChangeInfo = (JetChangeInfo) changeInfo;
|
||||||
for (JetFunctionDefinitionUsage primaryFunction : jetChangeInfo.getMethodDescriptor().getPrimaryFunctions()) {
|
for (JetCallableDefinitionUsage primaryFunction : jetChangeInfo.getMethodDescriptor().getPrimaryCallables()) {
|
||||||
primaryFunction.processUsage(jetChangeInfo, primaryFunction.getDeclaration());
|
primaryFunction.processUsage(jetChangeInfo, primaryFunction.getDeclaration());
|
||||||
}
|
}
|
||||||
jetChangeInfo.primaryMethodUpdated();
|
jetChangeInfo.primaryMethodUpdated();
|
||||||
|
|||||||
+7
-7
@@ -19,10 +19,10 @@ package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.refactoring.changeSignature.MethodDescriptor
|
import com.intellij.refactoring.changeSignature.MethodDescriptor
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
|
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetCallableDefinitionUsage
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
|
|
||||||
public trait JetMethodDescriptor : MethodDescriptor<JetParameterInfo, Visibility> {
|
public trait JetMethodDescriptor : MethodDescriptor<JetParameterInfo, Visibility> {
|
||||||
@@ -42,11 +42,11 @@ public trait JetMethodDescriptor : MethodDescriptor<JetParameterInfo, Visibility
|
|||||||
}
|
}
|
||||||
|
|
||||||
val baseDeclaration: PsiElement
|
val baseDeclaration: PsiElement
|
||||||
val baseDescriptor: FunctionDescriptor
|
val baseDescriptor: CallableDescriptor
|
||||||
|
|
||||||
val originalPrimaryFunction: JetFunctionDefinitionUsage<PsiElement>
|
val originalPrimaryCallable: JetCallableDefinitionUsage<PsiElement>
|
||||||
val primaryFunctions: Collection<JetFunctionDefinitionUsage<PsiElement>>
|
val primaryCallables: Collection<JetCallableDefinitionUsage<PsiElement>>
|
||||||
val affectedFunctions: Collection<UsageInfo>
|
val affectedCallables: Collection<UsageInfo>
|
||||||
|
|
||||||
val receiver: JetParameterInfo?
|
val receiver: JetParameterInfo?
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-22
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.compareDescriptors
|
import org.jetbrains.kotlin.idea.core.compareDescriptors
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetCallableDefinitionUsage
|
||||||
import org.jetbrains.kotlin.idea.references.JetReference
|
import org.jetbrains.kotlin.idea.references.JetReference
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.types.JetType
|
|||||||
import java.util.LinkedHashMap
|
import java.util.LinkedHashMap
|
||||||
|
|
||||||
public class JetParameterInfo(
|
public class JetParameterInfo(
|
||||||
val functionDescriptor: FunctionDescriptor,
|
val callableDescriptor: CallableDescriptor,
|
||||||
val originalIndex: Int = -1,
|
val originalIndex: Int = -1,
|
||||||
private var name: String,
|
private var name: String,
|
||||||
type: JetType? = null,
|
type: JetType? = null,
|
||||||
@@ -61,7 +61,7 @@ public class JetParameterInfo(
|
|||||||
object : JetTreeVisitorVoid() {
|
object : JetTreeVisitorVoid() {
|
||||||
private fun selfParameterOrNull(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
|
private fun selfParameterOrNull(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
|
||||||
return if (parameter is ValueParameterDescriptor &&
|
return if (parameter is ValueParameterDescriptor &&
|
||||||
compareDescriptors(project, parameter.getContainingDeclaration(), functionDescriptor)) {
|
compareDescriptors(project, parameter.getContainingDeclaration(), callableDescriptor)) {
|
||||||
parameter
|
parameter
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
@@ -69,12 +69,12 @@ public class JetParameterInfo(
|
|||||||
private fun selfReceiverOrNull(receiverDescriptor: DeclarationDescriptor?): DeclarationDescriptor? {
|
private fun selfReceiverOrNull(receiverDescriptor: DeclarationDescriptor?): DeclarationDescriptor? {
|
||||||
if (compareDescriptors(project,
|
if (compareDescriptors(project,
|
||||||
receiverDescriptor,
|
receiverDescriptor,
|
||||||
functionDescriptor.getExtensionReceiverParameter()?.getContainingDeclaration())) {
|
callableDescriptor.getExtensionReceiverParameter()?.getContainingDeclaration())) {
|
||||||
return receiverDescriptor
|
return receiverDescriptor
|
||||||
}
|
}
|
||||||
if (compareDescriptors(project,
|
if (compareDescriptors(project,
|
||||||
receiverDescriptor,
|
receiverDescriptor,
|
||||||
functionDescriptor.getDispatchReceiverParameter()?.getContainingDeclaration())) {
|
callableDescriptor.getDispatchReceiverParameter()?.getContainingDeclaration())) {
|
||||||
return receiverDescriptor
|
return receiverDescriptor
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@@ -93,7 +93,7 @@ public class JetParameterInfo(
|
|||||||
val descriptor = ref.resolveToDescriptors(context).singleOrNull()
|
val descriptor = ref.resolveToDescriptors(context).singleOrNull()
|
||||||
if (descriptor is ValueParameterDescriptor) return selfParameterOrNull(descriptor)
|
if (descriptor is ValueParameterDescriptor) return selfParameterOrNull(descriptor)
|
||||||
|
|
||||||
if (descriptor is PropertyDescriptor && functionDescriptor is ConstructorDescriptor) {
|
if (descriptor is PropertyDescriptor && callableDescriptor is ConstructorDescriptor) {
|
||||||
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? JetParameter
|
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? JetParameter
|
||||||
return parameter?.let { selfParameterOrNull(context[BindingContext.VALUE_PARAMETER, it]) }
|
return parameter?.let { selfParameterOrNull(context[BindingContext.VALUE_PARAMETER, it]) }
|
||||||
}
|
}
|
||||||
@@ -149,20 +149,20 @@ public class JetParameterInfo(
|
|||||||
throw UnsupportedOperationException()
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun renderType(parameterIndex: Int, inheritedFunction: JetFunctionDefinitionUsage<*>): String {
|
public fun renderType(parameterIndex: Int, inheritedCallable: JetCallableDefinitionUsage<*>): String {
|
||||||
val typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor() ?: return currentTypeText
|
val typeSubstitutor = inheritedCallable.getOrCreateTypeSubstitutor() ?: return currentTypeText
|
||||||
val currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor() ?: return currentTypeText
|
val currentBaseFunction = inheritedCallable.getBaseFunction().getCurrentCallableDescriptor() ?: return currentTypeText
|
||||||
val parameterType = currentBaseFunction.getValueParameters().get(parameterIndex).getType()
|
val parameterType = currentBaseFunction.getValueParameters().get(parameterIndex).getType()
|
||||||
return parameterType.renderTypeWithSubstitution(typeSubstitutor, currentTypeText, true)
|
return parameterType.renderTypeWithSubstitution(typeSubstitutor, currentTypeText, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getInheritedName(inheritedFunction: JetFunctionDefinitionUsage<*>): String {
|
public fun getInheritedName(inheritedCallable: JetCallableDefinitionUsage<*>): String {
|
||||||
if (!inheritedFunction.isInherited()) return name
|
if (!inheritedCallable.isInherited()) return name
|
||||||
|
|
||||||
val baseFunction = inheritedFunction.getBaseFunction()
|
val baseFunction = inheritedCallable.getBaseFunction()
|
||||||
val baseFunctionDescriptor = baseFunction.getOriginalFunctionDescriptor()
|
val baseFunctionDescriptor = baseFunction.getOriginalCallableDescriptor()
|
||||||
|
|
||||||
val inheritedFunctionDescriptor = inheritedFunction.getOriginalFunctionDescriptor()
|
val inheritedFunctionDescriptor = inheritedCallable.getOriginalCallableDescriptor()
|
||||||
val inheritedParameterDescriptors = inheritedFunctionDescriptor.getValueParameters()
|
val inheritedParameterDescriptors = inheritedFunctionDescriptor.getValueParameters()
|
||||||
if (originalIndex < 0
|
if (originalIndex < 0
|
||||||
|| originalIndex >= baseFunctionDescriptor.getValueParameters().size()
|
|| originalIndex >= baseFunctionDescriptor.getValueParameters().size()
|
||||||
@@ -177,18 +177,18 @@ public class JetParameterInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun requiresExplicitType(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): Boolean {
|
public fun requiresExplicitType(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): Boolean {
|
||||||
val inheritedFunctionDescriptor = inheritedFunction.getOriginalFunctionDescriptor()
|
val inheritedFunctionDescriptor = inheritedCallable.getOriginalCallableDescriptor()
|
||||||
if (inheritedFunctionDescriptor !is AnonymousFunctionDescriptor) return true
|
if (inheritedFunctionDescriptor !is AnonymousFunctionDescriptor) return true
|
||||||
|
|
||||||
if (originalIndex < 0) return !inheritedFunction.hasExpectedType()
|
if (originalIndex < 0) return !inheritedCallable.hasExpectedType()
|
||||||
|
|
||||||
val inheritedParameterDescriptor = inheritedFunctionDescriptor.getValueParameters().get(originalIndex)
|
val inheritedParameterDescriptor = inheritedFunctionDescriptor.getValueParameters().get(originalIndex)
|
||||||
val parameter = DescriptorToSourceUtils.descriptorToDeclaration(inheritedParameterDescriptor) as? JetParameter ?: return false
|
val parameter = DescriptorToSourceUtils.descriptorToDeclaration(inheritedParameterDescriptor) as? JetParameter ?: return false
|
||||||
return parameter.getTypeReference() != null
|
return parameter.getTypeReference() != null
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getDeclarationSignature(parameterIndex: Int, inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
|
public fun getDeclarationSignature(parameterIndex: Int, inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String {
|
||||||
val buffer = StringBuilder()
|
val buffer = StringBuilder()
|
||||||
|
|
||||||
if (modifierList != null) {
|
if (modifierList != null) {
|
||||||
@@ -199,13 +199,13 @@ public class JetParameterInfo(
|
|||||||
buffer.append(valOrVar).append(' ')
|
buffer.append(valOrVar).append(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.append(getInheritedName(inheritedFunction))
|
buffer.append(getInheritedName(inheritedCallable))
|
||||||
|
|
||||||
if (requiresExplicitType(inheritedFunction)) {
|
if (requiresExplicitType(inheritedCallable)) {
|
||||||
buffer.append(": ").append(renderType(parameterIndex, inheritedFunction))
|
buffer.append(": ").append(renderType(parameterIndex, inheritedCallable))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inheritedFunction.isInherited()) {
|
if (!inheritedCallable.isInherited()) {
|
||||||
defaultValueForParameter?.let { buffer.append(" = ").append(it.getText()) }
|
defaultValueForParameter?.let { buffer.append(" = ").append(it.getText()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,18 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetCallableDefinitionUsage
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
|
||||||
import org.jetbrains.kotlin.types.TypeProjection
|
|
||||||
import java.util.LinkedHashMap
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
|
||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
|
|
||||||
import org.jetbrains.kotlin.types.JetType
|
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
||||||
|
import java.util.LinkedHashMap
|
||||||
|
|
||||||
private fun getTypeSubstitution(baseType: JetType, derivedType: JetType): LinkedHashMap<TypeConstructor, TypeProjection>? {
|
private fun getTypeSubstitution(baseType: JetType, derivedType: JetType): LinkedHashMap<TypeConstructor, TypeProjection>? {
|
||||||
val substitutedType = TypeCheckingProcedure.findCorrespondingSupertype(derivedType, baseType) ?: return null
|
val substitutedType = TypeCheckingProcedure.findCorrespondingSupertype(derivedType, baseType) ?: return null
|
||||||
@@ -40,15 +35,15 @@ private fun getTypeSubstitution(baseType: JetType, derivedType: JetType): Linked
|
|||||||
return substitution
|
return substitution
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFunctionSubstitution(
|
private fun getCallableSubstitution(
|
||||||
baseFunction: FunctionDescriptor,
|
baseCallable: CallableDescriptor,
|
||||||
derivedFunction: FunctionDescriptor
|
derivedCallable: CallableDescriptor
|
||||||
): MutableMap<TypeConstructor, TypeProjection>? {
|
): MutableMap<TypeConstructor, TypeProjection>? {
|
||||||
val baseClass = baseFunction.getContainingDeclaration() as? ClassDescriptor ?: return null
|
val baseClass = baseCallable.getContainingDeclaration() as? ClassDescriptor ?: return null
|
||||||
val derivedClass = derivedFunction.getContainingDeclaration() as? ClassDescriptor ?: return null
|
val derivedClass = derivedCallable.getContainingDeclaration() as? ClassDescriptor ?: return null
|
||||||
val substitution = getTypeSubstitution(baseClass.getDefaultType(), derivedClass.getDefaultType()) ?: return null
|
val substitution = getTypeSubstitution(baseClass.getDefaultType(), derivedClass.getDefaultType()) ?: return null
|
||||||
|
|
||||||
for ((baseParam, derivedParam) in baseFunction.getTypeParameters() zip derivedFunction.getTypeParameters()) {
|
for ((baseParam, derivedParam) in baseCallable.getTypeParameters() zip derivedCallable.getTypeParameters()) {
|
||||||
substitution[baseParam.getTypeConstructor()] = TypeProjectionImpl(derivedParam.getDefaultType())
|
substitution[baseParam.getTypeConstructor()] = TypeProjectionImpl(derivedParam.getDefaultType())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,15 +54,15 @@ fun getTypeSubstitutor(baseType: JetType, derivedType: JetType): TypeSubstitutor
|
|||||||
return getTypeSubstitution(baseType, derivedType)?.let { TypeSubstitutor.create(it) }
|
return getTypeSubstitution(baseType, derivedType)?.let { TypeSubstitutor.create(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFunctionSubstitutor(
|
fun getCallableSubstitutor(
|
||||||
baseFunction: JetFunctionDefinitionUsage<*>,
|
baseFunction: JetCallableDefinitionUsage<*>,
|
||||||
derivedFunction: JetFunctionDefinitionUsage<*>
|
derivedCallable: JetCallableDefinitionUsage<*>
|
||||||
): TypeSubstitutor? {
|
): TypeSubstitutor? {
|
||||||
val currentBaseFunction = baseFunction.getCurrentFunctionDescriptor()
|
val currentBaseFunction = baseFunction.getCurrentCallableDescriptor()
|
||||||
val currentDerivedFunction = derivedFunction.getCurrentFunctionDescriptor()
|
val currentDerivedFunction = derivedCallable.getCurrentCallableDescriptor()
|
||||||
if (currentBaseFunction == null || currentDerivedFunction == null) return null
|
if (currentBaseFunction == null || currentDerivedFunction == null) return null
|
||||||
|
|
||||||
return getFunctionSubstitution(currentBaseFunction, currentDerivedFunction)?.let { TypeSubstitutor.create(it) }
|
return getCallableSubstitution(currentBaseFunction, currentDerivedFunction)?.let { TypeSubstitutor.create(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun JetType.renderTypeWithSubstitution(substitutor: TypeSubstitutor?, defaultText: String, inArgumentPosition: Boolean): String {
|
fun JetType.renderTypeWithSubstitution(substitutor: TypeSubstitutor?, defaultText: String, inArgumentPosition: Boolean): String {
|
||||||
|
|||||||
+2
-2
@@ -35,10 +35,10 @@ public class DeferredJavaMethodOverrideOrSAMUsage(
|
|||||||
): JavaMethodDeferredKotlinUsage<JetFunction>(function) {
|
): JavaMethodDeferredKotlinUsage<JetFunction>(function) {
|
||||||
override fun resolve(javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetFunction> {
|
override fun resolve(javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetFunction> {
|
||||||
return object : JavaMethodKotlinUsageWithDelegate<JetFunction>(function, javaMethodChangeInfo) {
|
return object : JavaMethodKotlinUsageWithDelegate<JetFunction>(function, javaMethodChangeInfo) {
|
||||||
override val delegateUsage = JetFunctionDefinitionUsage(
|
override val delegateUsage = JetCallableDefinitionUsage(
|
||||||
function,
|
function,
|
||||||
functionDescriptor,
|
functionDescriptor,
|
||||||
javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction,
|
javaMethodChangeInfo.methodDescriptor.originalPrimaryCallable,
|
||||||
samCallType
|
samCallType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -34,7 +34,7 @@ public abstract class JavaMethodKotlinUsageWithDelegate<T: PsiElement>(
|
|||||||
public class JavaMethodKotlinCallUsage(
|
public class JavaMethodKotlinCallUsage(
|
||||||
callElement: JetCallElement,
|
callElement: JetCallElement,
|
||||||
javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetCallElement>(callElement, javaMethodChangeInfo) {
|
javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetCallElement>(callElement, javaMethodChangeInfo) {
|
||||||
override protected val delegateUsage = JetFunctionCallUsage(psiElement, javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction)
|
override protected val delegateUsage = JetFunctionCallUsage(psiElement, javaMethodChangeInfo.methodDescriptor.originalPrimaryCallable)
|
||||||
}
|
}
|
||||||
|
|
||||||
public class JavaMethodKotlinDerivedDefinitionUsage(
|
public class JavaMethodKotlinDerivedDefinitionUsage(
|
||||||
@@ -42,10 +42,10 @@ public class JavaMethodKotlinDerivedDefinitionUsage(
|
|||||||
functionDescriptor: FunctionDescriptor,
|
functionDescriptor: FunctionDescriptor,
|
||||||
javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetFunction>(function, javaMethodChangeInfo) {
|
javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetFunction>(function, javaMethodChangeInfo) {
|
||||||
@suppress("CAST_NEVER_SUCCEEDS")
|
@suppress("CAST_NEVER_SUCCEEDS")
|
||||||
override protected val delegateUsage = JetFunctionDefinitionUsage(
|
override protected val delegateUsage = JetCallableDefinitionUsage(
|
||||||
psiElement,
|
psiElement,
|
||||||
functionDescriptor,
|
functionDescriptor,
|
||||||
javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction,
|
javaMethodChangeInfo.methodDescriptor.originalPrimaryCallable,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-67
@@ -26,9 +26,9 @@ import kotlin.Pair;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.ShortenPackage;
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.ShortenPackage;
|
||||||
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.idea.util.ShortenReferences;
|
|||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences.Options;
|
import org.jetbrains.kotlin.idea.util.ShortenReferences.Options;
|
||||||
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
|
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||||
import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersPackage;
|
import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersPackage;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||||
@@ -52,14 +53,14 @@ import java.util.List;
|
|||||||
|
|
||||||
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
|
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
|
||||||
|
|
||||||
public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageInfo<T> {
|
public class JetCallableDefinitionUsage<T extends PsiElement> extends JetUsageInfo<T> {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final FunctionDescriptor originalFunctionDescriptor;
|
private final CallableDescriptor originalCallableDescriptor;
|
||||||
|
|
||||||
private FunctionDescriptor currentFunctionDescriptor;
|
private CallableDescriptor currentCallableDescriptor;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JetFunctionDefinitionUsage<? extends PsiElement> baseFunction;
|
private final JetCallableDefinitionUsage<? extends PsiElement> baseFunction;
|
||||||
|
|
||||||
private final boolean hasExpectedType;
|
private final boolean hasExpectedType;
|
||||||
|
|
||||||
@@ -69,24 +70,25 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
@Nullable
|
@Nullable
|
||||||
private TypeSubstitutor typeSubstitutor;
|
private TypeSubstitutor typeSubstitutor;
|
||||||
|
|
||||||
public JetFunctionDefinitionUsage(
|
public JetCallableDefinitionUsage(
|
||||||
@NotNull T function,
|
@NotNull T function,
|
||||||
@NotNull FunctionDescriptor originalFunctionDescriptor,
|
@NotNull CallableDescriptor originalCallableDescriptor,
|
||||||
@Nullable JetFunctionDefinitionUsage<PsiElement> baseFunction,
|
@Nullable JetCallableDefinitionUsage<PsiElement> baseFunction,
|
||||||
@Nullable JetType samCallType) {
|
@Nullable JetType samCallType
|
||||||
|
) {
|
||||||
super(function);
|
super(function);
|
||||||
this.originalFunctionDescriptor = originalFunctionDescriptor;
|
this.originalCallableDescriptor = originalCallableDescriptor;
|
||||||
this.baseFunction = baseFunction != null ? baseFunction : this;
|
this.baseFunction = baseFunction != null ? baseFunction : this;
|
||||||
this.hasExpectedType = checkIfHasExpectedType(originalFunctionDescriptor, isInherited());
|
this.hasExpectedType = checkIfHasExpectedType(originalCallableDescriptor, isInherited());
|
||||||
this.samCallType = samCallType;
|
this.samCallType = samCallType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkIfHasExpectedType(@NotNull FunctionDescriptor functionDescriptor, boolean isInherited) {
|
private static boolean checkIfHasExpectedType(@NotNull CallableDescriptor callableDescriptor, boolean isInherited) {
|
||||||
if (!(functionDescriptor instanceof AnonymousFunctionDescriptor && isInherited)) return false;
|
if (!(callableDescriptor instanceof AnonymousFunctionDescriptor && isInherited)) return false;
|
||||||
|
|
||||||
JetFunctionLiteral functionLiteral =
|
JetFunctionLiteral functionLiteral =
|
||||||
(JetFunctionLiteral) DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);
|
(JetFunctionLiteral) DescriptorToSourceUtils.descriptorToDeclaration(callableDescriptor);
|
||||||
assert functionLiteral != null : "No declaration found for " + functionDescriptor;
|
assert functionLiteral != null : "No declaration found for " + callableDescriptor;
|
||||||
|
|
||||||
PsiElement parent = functionLiteral.getParent();
|
PsiElement parent = functionLiteral.getParent();
|
||||||
if (!(parent instanceof JetFunctionLiteralExpression)) return false;
|
if (!(parent instanceof JetFunctionLiteralExpression)) return false;
|
||||||
@@ -96,7 +98,7 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JetFunctionDefinitionUsage getBaseFunction() {
|
public JetCallableDefinitionUsage getBaseFunction() {
|
||||||
return baseFunction;
|
return baseFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +114,10 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
|
|
||||||
if (typeSubstitutor == null) {
|
if (typeSubstitutor == null) {
|
||||||
if (samCallType == null) {
|
if (samCallType == null) {
|
||||||
typeSubstitutor = ChangeSignaturePackage.getFunctionSubstitutor(baseFunction, this);
|
typeSubstitutor = ChangeSignaturePackage.getCallableSubstitutor(baseFunction, this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DeclarationDescriptor currentBaseDescriptor = baseFunction.getCurrentFunctionDescriptor();
|
DeclarationDescriptor currentBaseDescriptor = baseFunction.getCurrentCallableDescriptor();
|
||||||
DeclarationDescriptor classDescriptor = currentBaseDescriptor != null
|
DeclarationDescriptor classDescriptor = currentBaseDescriptor != null
|
||||||
? currentBaseDescriptor.getContainingDeclaration()
|
? currentBaseDescriptor.getContainingDeclaration()
|
||||||
: null;
|
: null;
|
||||||
@@ -140,71 +142,51 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public final FunctionDescriptor getOriginalFunctionDescriptor() {
|
public final CallableDescriptor getOriginalCallableDescriptor() {
|
||||||
return originalFunctionDescriptor;
|
return originalCallableDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public final FunctionDescriptor getCurrentFunctionDescriptor() {
|
public final CallableDescriptor getCurrentCallableDescriptor() {
|
||||||
if (currentFunctionDescriptor == null) {
|
if (currentCallableDescriptor == null) {
|
||||||
PsiElement element = getDeclaration();
|
PsiElement element = getDeclaration();
|
||||||
|
|
||||||
if (element instanceof JetFunction) {
|
if (element instanceof JetFunction || element instanceof JetProperty) {
|
||||||
currentFunctionDescriptor = (FunctionDescriptor) ResolvePackage.resolveToDescriptor((JetFunction) element);
|
currentCallableDescriptor = (CallableDescriptor) ResolvePackage.resolveToDescriptor((JetDeclaration) element);
|
||||||
}
|
}
|
||||||
else if (element instanceof JetClass) {
|
else if (element instanceof JetClass) {
|
||||||
currentFunctionDescriptor = ((ClassDescriptor) ResolvePackage.resolveToDescriptor((JetClass) element)).getUnsubstitutedPrimaryConstructor();
|
currentCallableDescriptor = ((ClassDescriptor) ResolvePackage.resolveToDescriptor((JetClass) element)).getUnsubstitutedPrimaryConstructor();
|
||||||
}
|
}
|
||||||
else if (element instanceof PsiMethod) {
|
else if (element instanceof PsiMethod) {
|
||||||
currentFunctionDescriptor = ResolvePackage.getJavaMethodDescriptor((PsiMethod) element);
|
currentCallableDescriptor = ResolvePackage.getJavaMethodDescriptor((PsiMethod) element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return currentFunctionDescriptor;
|
return currentCallableDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processUsage(JetChangeInfo changeInfo, PsiElement element) {
|
public boolean processUsage(JetChangeInfo changeInfo, PsiElement element) {
|
||||||
JetParameterList parameterList;
|
if (!(element instanceof JetNamedDeclaration)) return true;
|
||||||
|
|
||||||
JetPsiFactory psiFactory = JetPsiFactory(element.getProject());
|
JetPsiFactory psiFactory = JetPsiFactory(element.getProject());
|
||||||
if (element instanceof JetFunction) {
|
|
||||||
JetFunction function = (JetFunction) element;
|
|
||||||
parameterList = function.getValueParameterList();
|
|
||||||
|
|
||||||
if (changeInfo.isNameChanged()) {
|
if (changeInfo.isNameChanged()) {
|
||||||
PsiElement identifier = function.getNameIdentifier();
|
PsiElement identifier = ((JetCallableDeclaration) element).getNameIdentifier();
|
||||||
|
|
||||||
if (identifier != null) {
|
if (identifier != null) {
|
||||||
identifier.replace(psiFactory.createIdentifier(changeInfo.getNewName()));
|
identifier.replace(psiFactory.createIdentifier(changeInfo.getNewName()));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean returnTypeIsNeeded = (changeInfo.isRefactoringTarget(originalFunctionDescriptor)
|
|
||||||
|| !(function instanceof JetFunctionLiteral)
|
|
||||||
|| function.getTypeReference() != null) &&
|
|
||||||
!(function instanceof JetConstructor);
|
|
||||||
if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) {
|
|
||||||
function.setTypeReference(null);
|
|
||||||
String returnTypeText = changeInfo.renderReturnType((JetFunctionDefinitionUsage<PsiElement>) this);
|
|
||||||
|
|
||||||
//TODO use ChangeFunctionReturnTypeFix.invoke when JetTypeCodeFragment.getType() is ready
|
|
||||||
if (!KotlinBuiltIns.getInstance().getUnitType().toString().equals(returnTypeText)) {
|
|
||||||
ShortenPackage.addToShorteningWaitSet(
|
|
||||||
function.setTypeReference(JetPsiFactory(function).createType(returnTypeText)),
|
|
||||||
Options.DEFAULT
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
parameterList = ((JetClass) element).getPrimaryConstructorParameterList();
|
changeReturnTypeIfNeeded(changeInfo, element);
|
||||||
}
|
|
||||||
|
JetParameterList parameterList = PsiUtilPackage.getValueParameterList((JetNamedDeclaration) element);
|
||||||
|
|
||||||
if (changeInfo.isParameterSetOrOrderChanged()) {
|
if (changeInfo.isParameterSetOrOrderChanged()) {
|
||||||
processParameterListWithStructuralChanges(changeInfo, element, parameterList, psiFactory);
|
processParameterListWithStructuralChanges(changeInfo, element, parameterList, psiFactory);
|
||||||
}
|
}
|
||||||
else if (parameterList != null) {
|
else if (parameterList != null) {
|
||||||
int paramIndex = originalFunctionDescriptor.getExtensionReceiverParameter() != null ? 1 : 0;
|
int paramIndex = originalCallableDescriptor.getExtensionReceiverParameter() != null ? 1 : 0;
|
||||||
|
|
||||||
for (JetParameter parameter : parameterList.getParameters()) {
|
for (JetParameter parameter : parameterList.getParameters()) {
|
||||||
JetParameterInfo parameterInfo = changeInfo.getNewParameters()[paramIndex];
|
JetParameterInfo parameterInfo = changeInfo.getNewParameters()[paramIndex];
|
||||||
@@ -215,11 +197,11 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
ShortenPackage.addToShorteningWaitSet(parameterList, Options.DEFAULT);
|
ShortenPackage.addToShorteningWaitSet(parameterList, Options.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element instanceof JetFunction && changeInfo.isReceiverTypeChanged()) {
|
if (element instanceof JetCallableDeclaration && changeInfo.isReceiverTypeChanged()) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
String receiverTypeText = changeInfo.renderReceiverType((JetFunctionDefinitionUsage<PsiElement>) this);
|
String receiverTypeText = changeInfo.renderReceiverType((JetCallableDefinitionUsage<PsiElement>) this);
|
||||||
JetTypeReference receiverTypeRef = receiverTypeText != null ? psiFactory.createType(receiverTypeText) : null;
|
JetTypeReference receiverTypeRef = receiverTypeText != null ? psiFactory.createType(receiverTypeText) : null;
|
||||||
JetTypeReference newReceiverTypeRef = TypeRefHelpersPackage.setReceiverTypeReference((JetFunction) element, receiverTypeRef);
|
JetTypeReference newReceiverTypeRef = TypeRefHelpersPackage.setReceiverTypeReference((JetCallableDeclaration) element, receiverTypeRef);
|
||||||
if (newReceiverTypeRef != null) {
|
if (newReceiverTypeRef != null) {
|
||||||
ShortenPackage.addToShorteningWaitSet(newReceiverTypeRef, ShortenReferences.Options.DEFAULT);
|
ShortenPackage.addToShorteningWaitSet(newReceiverTypeRef, ShortenReferences.Options.DEFAULT);
|
||||||
}
|
}
|
||||||
@@ -232,6 +214,36 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void changeReturnTypeIfNeeded(JetChangeInfo changeInfo, PsiElement element) {
|
||||||
|
if (!(element instanceof JetCallableDeclaration)) return;
|
||||||
|
if (element instanceof JetConstructor) return;
|
||||||
|
|
||||||
|
JetCallableDeclaration callable = (JetCallableDeclaration) element;
|
||||||
|
|
||||||
|
boolean returnTypeIsNeeded;
|
||||||
|
if (element instanceof JetFunction) {
|
||||||
|
returnTypeIsNeeded = (changeInfo.isRefactoringTarget(originalCallableDescriptor) ||
|
||||||
|
!(callable instanceof JetFunctionLiteral) ||
|
||||||
|
callable.getTypeReference() != null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
returnTypeIsNeeded = element instanceof JetProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changeInfo.isReturnTypeChanged() && returnTypeIsNeeded) {
|
||||||
|
callable.setTypeReference(null);
|
||||||
|
String returnTypeText = changeInfo.renderReturnType((JetCallableDefinitionUsage<PsiElement>) this);
|
||||||
|
|
||||||
|
//TODO use ChangeFunctionReturnTypeFix.invoke when JetTypeCodeFragment.getType() is ready
|
||||||
|
if (!KotlinBuiltIns.getInstance().getUnitType().toString().equals(returnTypeText)) {
|
||||||
|
ShortenPackage.addToShorteningWaitSet(
|
||||||
|
callable.setTypeReference(JetPsiFactory(callable).createType(returnTypeText)),
|
||||||
|
Options.DEFAULT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void processParameterListWithStructuralChanges(
|
private void processParameterListWithStructuralChanges(
|
||||||
JetChangeInfo changeInfo,
|
JetChangeInfo changeInfo,
|
||||||
PsiElement element,
|
PsiElement element,
|
||||||
@@ -256,14 +268,14 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newParameterList = psiFactory.createFunctionLiteralParameterList(changeInfo.getNewParametersSignature(
|
newParameterList = psiFactory.createFunctionLiteralParameterList(changeInfo.getNewParametersSignature(
|
||||||
(JetFunctionDefinitionUsage<PsiElement>) this)
|
(JetCallableDefinitionUsage<PsiElement>) this)
|
||||||
);
|
);
|
||||||
canReplaceEntireList = true;
|
canReplaceEntireList = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (!(element instanceof JetProperty)) {
|
||||||
newParameterList = psiFactory.createParameterList(changeInfo.getNewParametersSignature(
|
newParameterList = psiFactory.createParameterList(changeInfo.getNewParametersSignature(
|
||||||
(JetFunctionDefinitionUsage<PsiElement>) this)
|
(JetCallableDefinitionUsage<PsiElement>) this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,14 +351,15 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
private static void changeVisibility(JetChangeInfo changeInfo, PsiElement element) {
|
private static void changeVisibility(JetChangeInfo changeInfo, PsiElement element) {
|
||||||
JetModifierKeywordToken newVisibilityToken = JetRefactoringUtil.getVisibilityToken(changeInfo.getNewVisibility());
|
JetModifierKeywordToken newVisibilityToken = JetRefactoringUtil.getVisibilityToken(changeInfo.getNewVisibility());
|
||||||
|
|
||||||
if (element instanceof JetFunction) {
|
if (element instanceof JetCallableDeclaration) {
|
||||||
((JetFunction)element).addModifier(newVisibilityToken);
|
((JetCallableDeclaration)element).addModifier(newVisibilityToken);
|
||||||
}
|
}
|
||||||
else {
|
else if (element instanceof JetClass) {
|
||||||
JetPrimaryConstructor constructor = ((JetClass) element).getPrimaryConstructor();
|
JetPrimaryConstructor constructor = ((JetClass) element).getPrimaryConstructor();
|
||||||
assert constructor != null : "Primary constructor should be created before changing visibility";
|
assert constructor != null : "Primary constructor should be created before changing visibility";
|
||||||
constructor.addModifier(newVisibilityToken);
|
constructor.addModifier(newVisibilityToken);
|
||||||
}
|
}
|
||||||
|
else throw new AssertionError("Invalid element: " + PsiUtilPackage.getElementTextWithContext(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeParameter(int parameterIndex, JetParameter parameter, JetParameterInfo parameterInfo) {
|
private void changeParameter(int parameterIndex, JetParameter parameter, JetParameterInfo parameterInfo) {
|
||||||
@@ -365,6 +378,7 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
}
|
}
|
||||||
else if (valOrVar != JetValVar.None) {
|
else if (valOrVar != JetValVar.None) {
|
||||||
PsiElement firstChild = parameter.getFirstChild();
|
PsiElement firstChild = parameter.getFirstChild();
|
||||||
|
//noinspection ConstantConditions
|
||||||
parameter.addBefore(valOrVar.createKeyword(psiFactory), firstChild);
|
parameter.addBefore(valOrVar.createKeyword(psiFactory), firstChild);
|
||||||
parameter.addBefore(psiFactory.createWhiteSpace(), firstChild);
|
parameter.addBefore(psiFactory.createWhiteSpace(), firstChild);
|
||||||
}
|
}
|
||||||
@@ -378,7 +392,7 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
|||||||
|
|
||||||
if (identifier != null) {
|
if (identifier != null) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
String newName = parameterInfo.getInheritedName((JetFunctionDefinitionUsage<PsiElement>) this);
|
String newName = parameterInfo.getInheritedName(this);
|
||||||
identifier.replace(psiFactory.createIdentifier(newName));
|
identifier.replace(psiFactory.createIdentifier(newName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -25,7 +25,7 @@ public class JetConstructorDelegationCallUsage(
|
|||||||
call: JetConstructorDelegationCall,
|
call: JetConstructorDelegationCall,
|
||||||
changeInfo: JetChangeInfo
|
changeInfo: JetChangeInfo
|
||||||
) : JetUsageInfo<JetConstructorDelegationCall>(call) {
|
) : JetUsageInfo<JetConstructorDelegationCall>(call) {
|
||||||
val delegate = JetFunctionCallUsage(call, changeInfo.methodDescriptor.originalPrimaryFunction)
|
val delegate = JetFunctionCallUsage(call, changeInfo.methodDescriptor.originalPrimaryCallable)
|
||||||
|
|
||||||
override fun processUsage(changeInfo: JetChangeInfo, element: JetConstructorDelegationCall): Boolean {
|
override fun processUsage(changeInfo: JetChangeInfo, element: JetConstructorDelegationCall): Boolean {
|
||||||
val isThisCall = element.isCallToThis()
|
val isThisCall = element.isCallToThis()
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class JetEnumEntryWithoutSuperCallUsage(enumEntry: JetEnumEntry) : JetUsa
|
|||||||
) as JetDelegatorToSuperCall
|
) as JetDelegatorToSuperCall
|
||||||
element.addBefore(psiFactory.createColon(), delegatorToSuperCall)
|
element.addBefore(psiFactory.createColon(), delegatorToSuperCall)
|
||||||
|
|
||||||
return JetFunctionCallUsage(delegatorToSuperCall, changeInfo.methodDescriptor.originalPrimaryFunction)
|
return JetFunctionCallUsage(delegatorToSuperCall, changeInfo.methodDescriptor.originalPrimaryCallable)
|
||||||
.processUsage(changeInfo, delegatorToSuperCall)
|
.processUsage(changeInfo, delegatorToSuperCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+67
-10
@@ -29,6 +29,7 @@ import kotlin.Unit;
|
|||||||
import kotlin.jvm.functions.Function1;
|
import kotlin.jvm.functions.Function1;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.codegen.PropertyCodegen;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.ShortenPackage;
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.ShortenPackage;
|
||||||
@@ -38,6 +39,9 @@ import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetParameterInfo;
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.ExtractionEnginePackage;
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.ExtractionEnginePackage;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler;
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler;
|
||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences;
|
import org.jetbrains.kotlin.idea.util.ShortenReferences;
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
|
||||||
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||||
@@ -75,11 +79,11 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
|||||||
|
|
||||||
private static final ShortenReferences.Options SHORTEN_ARGUMENTS_OPTIONS = new ShortenReferences.Options(true, true);
|
private static final ShortenReferences.Options SHORTEN_ARGUMENTS_OPTIONS = new ShortenReferences.Options(true, true);
|
||||||
|
|
||||||
private final JetFunctionDefinitionUsage<?> callee;
|
private final JetCallableDefinitionUsage<?> callee;
|
||||||
private final BindingContext context;
|
private final BindingContext context;
|
||||||
private final ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
private final ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
||||||
|
|
||||||
public JetFunctionCallUsage(@NotNull JetCallElement element, JetFunctionDefinitionUsage callee) {
|
public JetFunctionCallUsage(@NotNull JetCallElement element, JetCallableDefinitionUsage callee) {
|
||||||
super(element);
|
super(element);
|
||||||
this.callee = callee;
|
this.callee = callee;
|
||||||
this.context = ResolvePackage.analyze(element, BodyResolveMode.FULL);
|
this.context = ResolvePackage.analyze(element, BodyResolveMode.FULL);
|
||||||
@@ -88,13 +92,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean processUsage(JetChangeInfo changeInfo, JetCallElement element) {
|
public boolean processUsage(JetChangeInfo changeInfo, JetCallElement element) {
|
||||||
if (changeInfo.isNameChanged()) {
|
changeNameIfNeeded(changeInfo, element);
|
||||||
JetExpression callee = element.getCalleeExpression();
|
|
||||||
|
|
||||||
if (callee instanceof JetSimpleNameExpression) {
|
|
||||||
callee.replace(JetPsiFactory(getProject()).createSimpleName(changeInfo.getNewName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.getValueArgumentList() != null) {
|
if (element.getValueArgumentList() != null) {
|
||||||
if (changeInfo.isParameterSetOrOrderChanged()) {
|
if (changeInfo.isParameterSetOrOrderChanged()) {
|
||||||
@@ -118,6 +116,27 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isPropertyJavaUsage() {
|
||||||
|
return this.callee.getElement() instanceof JetProperty
|
||||||
|
&& resolvedCall != null && resolvedCall.getResultingDescriptor() instanceof JavaMethodDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void changeNameIfNeeded(JetChangeInfo changeInfo, JetCallElement element) {
|
||||||
|
if (!changeInfo.isNameChanged()) return;
|
||||||
|
|
||||||
|
JetExpression callee = element.getCalleeExpression();
|
||||||
|
if (!(callee instanceof JetSimpleNameExpression)) return;
|
||||||
|
|
||||||
|
String newName = changeInfo.getNewName();
|
||||||
|
if (isPropertyJavaUsage()) {
|
||||||
|
String currentName = ((JetSimpleNameExpression) callee).getReferencedName();
|
||||||
|
if (currentName.startsWith(JvmAbi.GETTER_PREFIX)) newName = PropertyCodegen.getterName(Name.identifier(newName));
|
||||||
|
else if (currentName.startsWith(JvmAbi.SETTER_PREFIX)) newName = PropertyCodegen.setterName(Name.identifier(newName));
|
||||||
|
}
|
||||||
|
|
||||||
|
callee.replace(JetPsiFactory(getProject()).createSimpleName(newName));
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JetExpression getReceiverExpressionIfMatched(
|
private JetExpression getReceiverExpressionIfMatched(
|
||||||
@NotNull ReceiverValue receiverValue,
|
@NotNull ReceiverValue receiverValue,
|
||||||
@@ -288,6 +307,11 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
|||||||
assert arguments != null : "Argument list is expected: " + element.getText();
|
assert arguments != null : "Argument list is expected: " + element.getText();
|
||||||
List<? extends ValueArgument> oldArguments = element.getValueArguments();
|
List<? extends ValueArgument> oldArguments = element.getValueArguments();
|
||||||
|
|
||||||
|
if (isPropertyJavaUsage()) {
|
||||||
|
updateJavaPropertyCall(changeInfo, element);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isNamedCall = oldArguments.size() > 1 && oldArguments.get(0).isNamed();
|
boolean isNamedCall = oldArguments.size() > 1 && oldArguments.get(0).isNamed();
|
||||||
StringBuilder parametersBuilder = new StringBuilder("(");
|
StringBuilder parametersBuilder = new StringBuilder("(");
|
||||||
boolean isFirst = true;
|
boolean isFirst = true;
|
||||||
@@ -388,7 +412,8 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
|||||||
|
|
||||||
//TODO: this is not correct!
|
//TODO: this is not correct!
|
||||||
JetValueArgument lastArgument = KotlinPackage.lastOrNull(newArgumentList.getArguments());
|
JetValueArgument lastArgument = KotlinPackage.lastOrNull(newArgumentList.getArguments());
|
||||||
boolean hasTrailingLambdaInArgumentListAfter = lastArgument != null && PsiPackage.unpackFunctionLiteral(lastArgument.getArgumentExpression()) != null;
|
boolean hasTrailingLambdaInArgumentListAfter =
|
||||||
|
lastArgument != null && PsiPackage.unpackFunctionLiteral(lastArgument.getArgumentExpression()) != null;
|
||||||
|
|
||||||
arguments = (JetValueArgumentList) arguments.replace(newArgumentList);
|
arguments = (JetValueArgumentList) arguments.replace(newArgumentList);
|
||||||
|
|
||||||
@@ -435,6 +460,38 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void updateJavaPropertyCall(JetChangeInfo changeInfo, JetCallElement element) {
|
||||||
|
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
||||||
|
JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
||||||
|
if (newReceiverInfo == originalReceiverInfo) return;
|
||||||
|
|
||||||
|
JetValueArgumentList arguments = element.getValueArgumentList();
|
||||||
|
assert arguments != null : "Argument list is expected: " + element.getText();
|
||||||
|
List<? extends ValueArgument> oldArguments = element.getValueArguments();
|
||||||
|
|
||||||
|
JetPsiFactory psiFactory = new JetPsiFactory(element.getProject());
|
||||||
|
|
||||||
|
JetValueArgument firstArgument = oldArguments.isEmpty() ? null : (JetValueArgument) oldArguments.get(0);
|
||||||
|
|
||||||
|
if (newReceiverInfo == null) {
|
||||||
|
if (firstArgument != null) arguments.removeArgument(firstArgument);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JetExpression defaultValueForCall = newReceiverInfo.getDefaultValueForCall();
|
||||||
|
if (defaultValueForCall == null) {
|
||||||
|
defaultValueForCall = psiFactory.createExpression("_");
|
||||||
|
}
|
||||||
|
JetValueArgument newReceiverArgument = psiFactory.createArgument(defaultValueForCall, null, false);
|
||||||
|
|
||||||
|
if (originalReceiverInfo != null) {
|
||||||
|
if (firstArgument != null) firstArgument.replace(newReceiverArgument);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arguments.addArgumentAfter(newReceiverArgument, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static JetExpression getReceiverExpression(@NotNull ReceiverValue receiver, @NotNull JetPsiFactory psiFactory) {
|
private static JetExpression getReceiverExpression(@NotNull ReceiverValue receiver, @NotNull JetPsiFactory psiFactory) {
|
||||||
if (receiver instanceof ExpressionReceiver) {
|
if (receiver instanceof ExpressionReceiver) {
|
||||||
|
|||||||
+2
-2
@@ -44,9 +44,9 @@ public abstract class JetImplicitReceiverUsage(callElement: JetElement): JetUsag
|
|||||||
public class JetImplicitThisToParameterUsage(
|
public class JetImplicitThisToParameterUsage(
|
||||||
callElement: JetElement,
|
callElement: JetElement,
|
||||||
val parameterInfo: JetParameterInfo,
|
val parameterInfo: JetParameterInfo,
|
||||||
val containingFunction: JetFunctionDefinitionUsage<*>
|
val containingCallable: JetCallableDefinitionUsage<*>
|
||||||
): JetImplicitReceiverUsage(callElement) {
|
): JetImplicitReceiverUsage(callElement) {
|
||||||
override fun getNewReceiverText(): String = parameterInfo.getInheritedName(containingFunction)
|
override fun getNewReceiverText(): String = parameterInfo.getInheritedName(containingCallable)
|
||||||
|
|
||||||
override fun processReplacedElement(element: JetElement) {
|
override fun processReplacedElement(element: JetElement) {
|
||||||
element.addToShorteningWaitSet(Options(removeThisLabels = true))
|
element.addToShorteningWaitSet(Options(removeThisLabels = true))
|
||||||
|
|||||||
+2
-2
@@ -46,7 +46,7 @@ public abstract class JetExplicitReferenceUsage<T: JetElement>(element: T) : Jet
|
|||||||
public class JetParameterUsage(
|
public class JetParameterUsage(
|
||||||
element: JetElement,
|
element: JetElement,
|
||||||
private val parameterInfo: JetParameterInfo,
|
private val parameterInfo: JetParameterInfo,
|
||||||
val containingFunction: JetFunctionDefinitionUsage<*>
|
val containingCallable: JetCallableDefinitionUsage<*>
|
||||||
) : JetExplicitReferenceUsage<JetElement>(element) {
|
) : JetExplicitReferenceUsage<JetElement>(element) {
|
||||||
override fun processReplacedElement(element: JetElement) {
|
override fun processReplacedElement(element: JetElement) {
|
||||||
val qualifiedExpression = element.getParent() as? JetQualifiedExpression
|
val qualifiedExpression = element.getParent() as? JetQualifiedExpression
|
||||||
@@ -56,7 +56,7 @@ public class JetParameterUsage(
|
|||||||
|
|
||||||
override fun getReplacementText(changeInfo: JetChangeInfo): String =
|
override fun getReplacementText(changeInfo: JetChangeInfo): String =
|
||||||
if (changeInfo.receiverParameterInfo != parameterInfo) {
|
if (changeInfo.receiverParameterInfo != parameterInfo) {
|
||||||
parameterInfo.getInheritedName(containingFunction)
|
parameterInfo.getInheritedName(containingCallable)
|
||||||
} else "this@${changeInfo.getNewName()}"
|
} else "this@${changeInfo.getNewName()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.usages
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetChangeInfo
|
||||||
|
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||||
|
import org.jetbrains.kotlin.psi.JetQualifiedExpression
|
||||||
|
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||||
|
import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
|
|
||||||
|
public class JetPropertyCallUsage(element: JetSimpleNameExpression): JetUsageInfo<JetSimpleNameExpression>(element) {
|
||||||
|
private val resolvedCall = element.getResolvedCall(element.analyze())
|
||||||
|
|
||||||
|
override fun processUsage(changeInfo: JetChangeInfo, element: JetSimpleNameExpression): Boolean {
|
||||||
|
updateName(changeInfo, element)
|
||||||
|
updateReceiver(changeInfo, element)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateName(changeInfo: JetChangeInfo, element: JetSimpleNameExpression) {
|
||||||
|
if (changeInfo.isNameChanged()) {
|
||||||
|
element.getReference()?.handleElementRename(changeInfo.getNewName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateReceiver(changeInfo: JetChangeInfo, element: JetSimpleNameExpression) {
|
||||||
|
val newReceiver = changeInfo.receiverParameterInfo
|
||||||
|
val oldReceiver = changeInfo.methodDescriptor.receiver
|
||||||
|
if (newReceiver == oldReceiver) return
|
||||||
|
|
||||||
|
val elementToReplace = element.getQualifiedExpressionForSelectorOrThis()
|
||||||
|
|
||||||
|
// Do not add extension receiver to calls with explicit dispatch receiver
|
||||||
|
if (newReceiver != null
|
||||||
|
&& elementToReplace is JetQualifiedExpression
|
||||||
|
&& resolvedCall?.getDispatchReceiver() is ExpressionReceiver) return
|
||||||
|
|
||||||
|
val replacingElement = newReceiver?.let {
|
||||||
|
val psiFactory = JetPsiFactory(getProject())
|
||||||
|
val receiver = it.defaultValueForCall ?: psiFactory.createExpression("_")
|
||||||
|
psiFactory.createExpressionByPattern("$0.$1", receiver, element)
|
||||||
|
} ?: element
|
||||||
|
|
||||||
|
elementToReplace.replace(replacingElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
-1
@@ -17,9 +17,19 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature.usages
|
package org.jetbrains.kotlin.idea.refactoring.changeSignature.usages
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.refactoring.changeSignature.JavaChangeInfo
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
|
|
||||||
public class KotlinWrapperForJavaUsageInfos(
|
public class KotlinWrapperForJavaUsageInfos(
|
||||||
|
val javaChangeInfo: JavaChangeInfo,
|
||||||
val javaUsageInfos: Array<UsageInfo>,
|
val javaUsageInfos: Array<UsageInfo>,
|
||||||
val primaryMethod: PsiElement
|
val primaryMethod: PsiElement
|
||||||
): UsageInfo(primaryMethod)
|
): UsageInfo(primaryMethod) {
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return javaChangeInfo.getMethod().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return other == this || (other is KotlinWrapperForJavaUsageInfos && javaChangeInfo.getMethod() == other.javaChangeInfo.getMethod())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+3
-11
@@ -32,6 +32,7 @@ import com.intellij.usageView.UsageInfo
|
|||||||
import org.jetbrains.kotlin.idea.JetFileType
|
import org.jetbrains.kotlin.idea.JetFileType
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.isMultiLine
|
import org.jetbrains.kotlin.idea.core.refactoring.isMultiLine
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.runRefactoringWithPostprocessing
|
import org.jetbrains.kotlin.idea.core.refactoring.runRefactoringWithPostprocessing
|
||||||
|
import org.jetbrains.kotlin.idea.core.refactoring.validateElement
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinExtractFunctionDialog
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinExtractFunctionDialog
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinParameterTablePanel
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinParameterTablePanel
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||||
@@ -233,18 +234,9 @@ public class KotlinIntroduceParameterDialog private constructor(
|
|||||||
override fun createCenterPanel() = null
|
override fun createCenterPanel() = null
|
||||||
|
|
||||||
override fun canRun() {
|
override fun canRun() {
|
||||||
fun validateElement(e: PsiElement, errorMessage: String) {
|
|
||||||
try {
|
|
||||||
AnalyzingUtils.checkForSyntacticErrors(e)
|
|
||||||
}
|
|
||||||
catch(e: Exception) {
|
|
||||||
throw ConfigurationException(errorMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val psiFactory = JetPsiFactory(myProject)
|
val psiFactory = JetPsiFactory(myProject)
|
||||||
validateElement(psiFactory.createType(nameField.getEnteredName()), "Invalid parameter name")
|
psiFactory.createSimpleName(nameField.getEnteredName()).validateElement("Invalid parameter name")
|
||||||
validateElement(psiFactory.createType(typeField.getEnteredName()), "Invalid parameter type")
|
psiFactory.createType(typeField.getEnteredName()).validateElement("Invalid parameter type")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doAction() {
|
override fun doAction() {
|
||||||
|
|||||||
+1
-1
@@ -142,7 +142,7 @@ fun IntroduceParameterDescriptor.performRefactoring() {
|
|||||||
.forEach { methodDescriptor.removeParameter(it) }
|
.forEach { methodDescriptor.removeParameter(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val parameterInfo = JetParameterInfo(functionDescriptor = callableDescriptor,
|
val parameterInfo = JetParameterInfo(callableDescriptor = callableDescriptor,
|
||||||
name = newParameterName,
|
name = newParameterName,
|
||||||
defaultValueForCall = if (withDefaultValue) null else newArgumentValue,
|
defaultValueForCall = if (withDefaultValue) null else newArgumentValue,
|
||||||
defaultValueForParameter = if (withDefaultValue) newArgumentValue else null,
|
defaultValueForParameter = if (withDefaultValue) newArgumentValue else null,
|
||||||
|
|||||||
+3
-3
@@ -77,7 +77,7 @@ public class KotlinIntroduceParameterMethodUsageProcessor : IntroduceParameterMe
|
|||||||
|
|
||||||
// Temporarily assume that the new parameter is of Any type. Actual type is substituted during the signature update phase
|
// Temporarily assume that the new parameter is of Any type. Actual type is substituted during the signature update phase
|
||||||
val defaultValueForCall = (data.getParameterInitializer().getExpression()!! as? PsiExpression)?.let { it.j2k() }
|
val defaultValueForCall = (data.getParameterInitializer().getExpression()!! as? PsiExpression)?.let { it.j2k() }
|
||||||
changeInfo.addParameter(JetParameterInfo(functionDescriptor = psiMethodDescriptor,
|
changeInfo.addParameter(JetParameterInfo(callableDescriptor = psiMethodDescriptor,
|
||||||
name = data.getParameterName(),
|
name = data.getParameterName(),
|
||||||
type = KotlinBuiltIns.getInstance().getAnyType(),
|
type = KotlinBuiltIns.getInstance().getAnyType(),
|
||||||
defaultValueForCall = defaultValueForCall))
|
defaultValueForCall = defaultValueForCall))
|
||||||
@@ -100,7 +100,7 @@ public class KotlinIntroduceParameterMethodUsageProcessor : IntroduceParameterMe
|
|||||||
.map { it.unwrapped }
|
.map { it.unwrapped }
|
||||||
.filterIsInstance<JetFunction>()
|
.filterIsInstance<JetFunction>()
|
||||||
return (kotlinFunctions + element).all {
|
return (kotlinFunctions + element).all {
|
||||||
JetFunctionDefinitionUsage(it, changeInfo.originalBaseFunctionDescriptor, null, null).processUsage(changeInfo, it)
|
JetCallableDefinitionUsage(it, changeInfo.originalBaseFunctionDescriptor, null, null).processUsage(changeInfo, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ public class KotlinIntroduceParameterMethodUsageProcessor : IntroduceParameterMe
|
|||||||
(JetConstructorDelegationCallUsage(callElement, changeInfo) as JetUsageInfo<JetCallElement>)
|
(JetConstructorDelegationCallUsage(callElement, changeInfo) as JetUsageInfo<JetCallElement>)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetFunctionCallUsage(callElement, changeInfo.methodDescriptor.originalPrimaryFunction)
|
JetFunctionCallUsage(callElement, changeInfo.methodDescriptor.originalPrimaryCallable)
|
||||||
}
|
}
|
||||||
return delegateUsage.processUsage(changeInfo, callElement)
|
return delegateUsage.processUsage(changeInfo, callElement)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import com.intellij.lang.java.JavaLanguage
|
import com.intellij.lang.java.JavaLanguage
|
||||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
|
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
|
||||||
|
import com.intellij.openapi.options.ConfigurationException
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.refactoring.listeners.RefactoringEventData
|
import com.intellij.refactoring.listeners.RefactoringEventData
|
||||||
import com.intellij.refactoring.listeners.RefactoringEventListener
|
import com.intellij.refactoring.listeners.RefactoringEventListener
|
||||||
@@ -88,6 +89,7 @@ import org.jetbrains.kotlin.j2k.ConverterSettings
|
|||||||
import org.jetbrains.kotlin.j2k.IdeaReferenceSearcher
|
import org.jetbrains.kotlin.j2k.IdeaReferenceSearcher
|
||||||
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
|
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
|
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||||
|
|
||||||
fun <T: Any> PsiElement.getAndRemoveCopyableUserData(key: Key<T>): T? {
|
fun <T: Any> PsiElement.getAndRemoveCopyableUserData(key: Key<T>): T? {
|
||||||
val data = getCopyableUserData(key)
|
val data = getCopyableUserData(key)
|
||||||
@@ -604,4 +606,14 @@ public fun (() -> Any).runRefactoringWithPostprocessing(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
this()
|
this()
|
||||||
|
}
|
||||||
|
|
||||||
|
@throws(ConfigurationException::class)
|
||||||
|
public fun JetElement.validateElement(errorMessage: String) {
|
||||||
|
try {
|
||||||
|
AnalyzingUtils.checkForSyntacticErrors(this)
|
||||||
|
}
|
||||||
|
catch(e: Exception) {
|
||||||
|
throw ConfigurationException(errorMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getP(String receiver) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(String receiver, int value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP("");
|
||||||
|
new A().setP("", 1);
|
||||||
|
|
||||||
|
new B().getP("");
|
||||||
|
new B().setP("", 2);
|
||||||
|
|
||||||
|
new J().getP("");
|
||||||
|
new J().setP("", 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open var <caret>String.p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var String.p: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
with(B()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
with(J()) {
|
||||||
|
val t = getP("")
|
||||||
|
setP("", 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getP() {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(2);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open var <caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var p: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
with(B()) {
|
||||||
|
val t = p
|
||||||
|
p = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
with(J()) {
|
||||||
|
val t = getP()
|
||||||
|
setP(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
open class A {
|
||||||
|
open var <caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t1 = A().p
|
||||||
|
A().p = 1
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Explicit receiver is already present in call element: A().p
|
||||||
|
Explicit receiver is already present in call element: A().p
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import test.TestPackage;
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
TestPackage.getP(A());
|
||||||
|
TestPackage.setP(A(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
open var <caret>A.p: Int
|
||||||
|
get() = 1
|
||||||
|
set(value: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t = A().p
|
||||||
|
A().p = 1
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import test.TestPackage;
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
TestPackage.getP();
|
||||||
|
TestPackage.setP(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
open var <caret>p: Int
|
||||||
|
get() = 1
|
||||||
|
set(value: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getS() {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setS(@NotNull String value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getS();
|
||||||
|
new A().setS(1);
|
||||||
|
|
||||||
|
new B().getS();
|
||||||
|
new B().setS(2);
|
||||||
|
|
||||||
|
new J().getS();
|
||||||
|
new J().setS(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
open class A {
|
||||||
|
open var <caret>s: String = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var s: String = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t1 = A().s
|
||||||
|
A().s = 1
|
||||||
|
|
||||||
|
val t2 = B().s
|
||||||
|
B().s = 2
|
||||||
|
|
||||||
|
val t3 = J().getS()
|
||||||
|
J().setS(3)
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getP() {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(2);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
open class A {
|
||||||
|
open var <caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var p: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val t1 = A().p
|
||||||
|
A().p = 1
|
||||||
|
|
||||||
|
val t2 = B().p
|
||||||
|
B().p = 2
|
||||||
|
|
||||||
|
val t3 = J().getP()
|
||||||
|
J().setP(3)
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getP(int receiver) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int receiver, int value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP("");
|
||||||
|
new A().setP("", 1);
|
||||||
|
|
||||||
|
new B().getP("");
|
||||||
|
new B().setP("", 2);
|
||||||
|
|
||||||
|
new J().getP("");
|
||||||
|
new J().setP("", 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open var Int.<caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var Int.p: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
with(B()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
with(J()) {
|
||||||
|
val t = getP("")
|
||||||
|
setP("", 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getP(String receiver) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(String receiver, int value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP("");
|
||||||
|
new A().setP("", 1);
|
||||||
|
|
||||||
|
new B().getP("");
|
||||||
|
new B().setP("", 2);
|
||||||
|
|
||||||
|
new J().getP("");
|
||||||
|
new J().setP("", 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open var String.<caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var String.p: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
with(B()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
with(J()) {
|
||||||
|
val t = getP("")
|
||||||
|
setP("", 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import test.TestPackage;
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
TestPackage.getP(new A());
|
||||||
|
TestPackage.setP(new A(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
open var String.<caret>p: Int
|
||||||
|
get() = 1
|
||||||
|
set(value: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val t1 = A().p
|
||||||
|
A().p = 1
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import test.TestPackage;
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
TestPackage.getP(new A());
|
||||||
|
TestPackage.setP(new A(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
open var A.<caret>p: Int
|
||||||
|
get() = 1
|
||||||
|
set(value: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val t1 = A().p
|
||||||
|
A().p = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getP() {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(int value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP();
|
||||||
|
new A().setP(1);
|
||||||
|
|
||||||
|
new B().getP();
|
||||||
|
new B().setP(2);
|
||||||
|
|
||||||
|
new J().getP();
|
||||||
|
new J().setP(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open var <caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var p: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
with(B()) {
|
||||||
|
val t = p
|
||||||
|
p = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
with(J()) {
|
||||||
|
val t = getP()
|
||||||
|
setP(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Override;
|
||||||
|
|
||||||
|
class J extends A {
|
||||||
|
private int p;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getP(String receiver) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setP(String receiver, int value) {
|
||||||
|
p = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
new A().getP("");
|
||||||
|
new A().setP("", 1);
|
||||||
|
|
||||||
|
new B().getP("");
|
||||||
|
new B().setP("", 2);
|
||||||
|
|
||||||
|
new J().getP("");
|
||||||
|
new J().setP("", 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open var String.<caret>p: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B: A() {
|
||||||
|
override var String.p: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
with(B()) {
|
||||||
|
val t = "".p
|
||||||
|
"".p = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
with(J()) {
|
||||||
|
val t = getP("")
|
||||||
|
setP("", 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import test.TestPackage;
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
TestPackage.getP();
|
||||||
|
TestPackage.setP(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
open var <caret>p: Int
|
||||||
|
get() = 1
|
||||||
|
set(value: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val t1 = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import test.TestPackage;
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
static void test() {
|
||||||
|
TestPackage.getP(new A());
|
||||||
|
TestPackage.setP(new A(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public inline fun <T, R> with(receiver: T, f: T.() -> R): R = receiver.f()
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
open var A.<caret>p: Int
|
||||||
|
get() = 1
|
||||||
|
set(value: Int) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
with(A()) {
|
||||||
|
val t = p
|
||||||
|
p = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
val t1 = A().p
|
||||||
|
A().p = 1
|
||||||
|
}
|
||||||
+65
-4
@@ -33,7 +33,7 @@ import com.intellij.util.VisibilityUtil;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
import org.jetbrains.kotlin.descriptors.Visibilities;
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle;
|
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle;
|
||||||
@@ -995,6 +995,67 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testChangeProperty() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
changeInfo.setNewName("s");
|
||||||
|
changeInfo.setNewReturnTypeText("String");
|
||||||
|
doTest(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAddPropertyReceiverConflict() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
JetParameterInfo newParameter = new JetParameterInfo(changeInfo.getMethodDescriptor().getBaseDescriptor(),
|
||||||
|
-1, "receiver", KotlinBuiltIns.getInstance().getStringType(), null,
|
||||||
|
new JetPsiFactory(getProject()).createExpression("\"\""), JetValVar.None, null);
|
||||||
|
changeInfo.setReceiverParameterInfo(newParameter);
|
||||||
|
doTestConflict(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAddPropertyReceiver() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
JetParameterInfo newParameter = new JetParameterInfo(changeInfo.getMethodDescriptor().getBaseDescriptor(),
|
||||||
|
-1, "receiver", KotlinBuiltIns.getInstance().getStringType(), null,
|
||||||
|
new JetPsiFactory(getProject()).createExpression("\"\""), JetValVar.None, null);
|
||||||
|
changeInfo.setReceiverParameterInfo(newParameter);
|
||||||
|
doTest(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChangePropertyReceiver() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
changeInfo.getReceiverParameterInfo().setCurrentTypeText("Int");
|
||||||
|
doTest(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRemovePropertyReceiver() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
changeInfo.setReceiverParameterInfo(null);
|
||||||
|
doTest(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAddTopLevelPropertyReceiver() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
JetParameterInfo newParameter = new JetParameterInfo(changeInfo.getMethodDescriptor().getBaseDescriptor(),
|
||||||
|
-1, "receiver", null, null,
|
||||||
|
new JetPsiFactory(getProject()).createExpression("A()"), JetValVar.None, null);
|
||||||
|
newParameter.setCurrentTypeText("test.A");
|
||||||
|
changeInfo.setReceiverParameterInfo(newParameter);
|
||||||
|
doTest(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChangeTopLevelPropertyReceiver() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
changeInfo.getReceiverParameterInfo().setCurrentTypeText("String");
|
||||||
|
doTest(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRemoveTopLevelPropertyReceiver() throws Exception {
|
||||||
|
JetChangeInfo changeInfo = getChangeInfo();
|
||||||
|
changeInfo.setReceiverParameterInfo(null);
|
||||||
|
doTest(changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
protected String getTestDataPath() {
|
protected String getTestDataPath() {
|
||||||
@@ -1039,11 +1100,11 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
|
|||||||
PsiElement context = file.findElementAt(editor.getCaretModel().getOffset());
|
PsiElement context = file.findElementAt(editor.getCaretModel().getOffset());
|
||||||
assertNotNull(context);
|
assertNotNull(context);
|
||||||
|
|
||||||
FunctionDescriptor functionDescriptor = JetChangeSignatureHandler.findDescriptor(element, project, editor, bindingContext);
|
CallableDescriptor callableDescriptor = JetChangeSignatureHandler.findDescriptor(element, project, editor, bindingContext);
|
||||||
assertNotNull(functionDescriptor);
|
assertNotNull(callableDescriptor);
|
||||||
|
|
||||||
return ChangeSignaturePackage.createChangeInfo(
|
return ChangeSignaturePackage.createChangeInfo(
|
||||||
project, functionDescriptor, JetChangeSignatureHandler.getConfiguration(), bindingContext, context);
|
project, callableDescriptor, JetChangeSignatureHandler.getConfiguration(), bindingContext, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JavaRefactoringProvider {
|
private class JavaRefactoringProvider {
|
||||||
|
|||||||
Reference in New Issue
Block a user