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.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
|
||||
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 {
|
||||
JetParameterInfo parameterInfo =
|
||||
getNewParameterInfo(originalDescriptor.getBaseDescriptor(), bindingContext, argument, validator);
|
||||
getNewParameterInfo((FunctionDescriptor) originalDescriptor.getBaseDescriptor(), bindingContext, argument, validator);
|
||||
typesToShorten.add(parameterInfo.getOriginalType());
|
||||
|
||||
if (expression != null) {
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ object CreateParameterActionFactory: JetSingleIntentionActionFactory() {
|
||||
return CreateParameterFromUsageFix(
|
||||
functionDescriptor,
|
||||
context,
|
||||
JetParameterInfo(functionDescriptor = functionDescriptor,
|
||||
JetParameterInfo(callableDescriptor = functionDescriptor,
|
||||
name = refExpr.getReferencedName(),
|
||||
type = paramType,
|
||||
valOrVar = valOrVar),
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public object CreateParameterByNamedArgumentActionFactory: JetSingleIntentionAct
|
||||
if (paramType.hasTypeParametersToAdd(functionDescriptor, context)) return null
|
||||
|
||||
val parameterInfo = JetParameterInfo(
|
||||
functionDescriptor = functionDescriptor,
|
||||
callableDescriptor = functionDescriptor,
|
||||
name = name,
|
||||
type = paramType,
|
||||
defaultValueForCall = argumentExpression
|
||||
|
||||
@@ -19,28 +19,35 @@ package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
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.util.VisibilityUtil
|
||||
import org.jetbrains.kotlin.asJava.*
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
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.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.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.idea.project.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMethodDescriptor.Kind
|
||||
import java.util.*
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
public class JetChangeInfo(
|
||||
val methodDescriptor: JetMethodDescriptor,
|
||||
@@ -61,7 +68,7 @@ public class JetChangeInfo(
|
||||
}
|
||||
|
||||
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 {
|
||||
val map = HashMap<String, Int>()
|
||||
@@ -80,13 +87,7 @@ public class JetChangeInfo(
|
||||
}
|
||||
|
||||
private var isPrimaryMethodUpdated: Boolean = false
|
||||
private var javaChangeInfo: JavaChangeInfo? = null
|
||||
|
||||
private fun getCurrentPsiMethod(): PsiMethod? {
|
||||
val psiMethods = getMethod().toLightMethods()
|
||||
assert(psiMethods.size() <= 1) { "Multiple light methods: " + getMethod().getText() }
|
||||
return psiMethods.firstOrNull()
|
||||
}
|
||||
private var javaChangeInfos: List<JavaChangeInfo>? = null
|
||||
|
||||
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 getNonReceiverParameters(): List<JetParameterInfo> {
|
||||
if (methodDescriptor.baseDeclaration is JetProperty) return emptyList()
|
||||
return receiverParameterInfo?.let { receiver -> newParameters.filter { it != receiver } } ?: newParameters
|
||||
}
|
||||
|
||||
@@ -146,7 +148,7 @@ public class JetChangeInfo(
|
||||
|
||||
override fun getLanguage(): Language = JetLanguage.INSTANCE
|
||||
|
||||
public fun getNewSignature(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
|
||||
public fun getNewSignature(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String {
|
||||
val buffer = StringBuilder()
|
||||
|
||||
val defaultVisibility = if (kind.isConstructor) Visibilities.PUBLIC else Visibilities.INTERNAL
|
||||
@@ -174,7 +176,7 @@ public class JetChangeInfo(
|
||||
buffer.append(name)
|
||||
}
|
||||
|
||||
buffer.append(getNewParametersSignature(inheritedFunction))
|
||||
buffer.append(getNewParametersSignature(inheritedCallable))
|
||||
|
||||
if (newReturnType != null && !KotlinBuiltIns.isUnit(newReturnType) && kind == Kind.FUNCTION)
|
||||
buffer.append(": ").append(newReturnTypeText)
|
||||
@@ -182,63 +184,75 @@ public class JetChangeInfo(
|
||||
return buffer.toString()
|
||||
}
|
||||
|
||||
public fun isRefactoringTarget(inheritedFunctionDescriptor: FunctionDescriptor?): Boolean {
|
||||
return inheritedFunctionDescriptor != null
|
||||
&& getMethod() == DescriptorToSourceUtils.descriptorToDeclaration(inheritedFunctionDescriptor)
|
||||
public fun isRefactoringTarget(inheritedCallableDescriptor: CallableDescriptor?): Boolean {
|
||||
return inheritedCallableDescriptor != null
|
||||
&& getMethod() == DescriptorToSourceUtils.descriptorToDeclaration(inheritedCallableDescriptor)
|
||||
}
|
||||
|
||||
public fun getNewParametersSignature(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
|
||||
public fun getNewParametersSignature(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String {
|
||||
val signatureParameters = getNonReceiverParameters()
|
||||
|
||||
val isLambda = inheritedFunction.getDeclaration() is JetFunctionLiteral
|
||||
if (isLambda && signatureParameters.size() == 1 && !signatureParameters.get(0).requiresExplicitType(inheritedFunction)) {
|
||||
return signatureParameters.get(0).getDeclarationSignature(0, inheritedFunction)
|
||||
val isLambda = inheritedCallable.getDeclaration() is JetFunctionLiteral
|
||||
if (isLambda && signatureParameters.size() == 1 && !signatureParameters.get(0).requiresExplicitType(inheritedCallable)) {
|
||||
return signatureParameters.get(0).getDeclarationSignature(0, inheritedCallable)
|
||||
}
|
||||
|
||||
return signatureParameters.indices
|
||||
.map { i -> signatureParameters[i].getDeclarationSignature(i, inheritedFunction) }
|
||||
.map { i -> signatureParameters[i].getDeclarationSignature(i, inheritedCallable) }
|
||||
.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 typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor() ?: return receiverTypeText
|
||||
val currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor() ?: return receiverTypeText
|
||||
val typeSubstitutor = inheritedCallable.getOrCreateTypeSubstitutor() ?: return receiverTypeText
|
||||
val currentBaseFunction = inheritedCallable.getBaseFunction().getCurrentCallableDescriptor() ?: return receiverTypeText
|
||||
return currentBaseFunction.getExtensionReceiverParameter()!!.getType().renderTypeWithSubstitution(typeSubstitutor, receiverTypeText, false)
|
||||
}
|
||||
|
||||
public fun renderReturnType(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): String {
|
||||
val typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor() ?: return newReturnTypeText
|
||||
val currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor() ?: return newReturnTypeText
|
||||
public fun renderReturnType(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): String {
|
||||
val typeSubstitutor = inheritedCallable.getOrCreateTypeSubstitutor() ?: return newReturnTypeText
|
||||
val currentBaseFunction = inheritedCallable.getBaseFunction().getCurrentCallableDescriptor() ?: return newReturnTypeText
|
||||
return currentBaseFunction.getReturnType().renderTypeWithSubstitution(typeSubstitutor, newReturnTypeText, false)
|
||||
}
|
||||
|
||||
public fun primaryMethodUpdated() {
|
||||
isPrimaryMethodUpdated = true
|
||||
javaChangeInfo = null
|
||||
javaChangeInfos = null
|
||||
}
|
||||
|
||||
public fun getOrCreateJavaChangeInfo(): JavaChangeInfo? {
|
||||
if (ProjectStructureUtil.isJsKotlinModule(getMethod().getContainingFile() as JetFile)) return null
|
||||
public fun getOrCreateJavaChangeInfos(): List<JavaChangeInfo>? {
|
||||
/*
|
||||
* 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) {
|
||||
val currentPsiMethod = getCurrentPsiMethod()
|
||||
if (originalPsiMethod == null || currentPsiMethod == null) 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)
|
||||
*/
|
||||
val javaVisibility = if (isPrimaryMethodUpdated)
|
||||
fun createJavaChangeInfo(originalPsiMethod: PsiMethod,
|
||||
currentPsiMethod: PsiMethod,
|
||||
newName: String,
|
||||
newReturnType: PsiType?,
|
||||
newParameters: Array<ParameterInfoImpl>
|
||||
): JavaChangeInfo? {
|
||||
val newVisibility = if (isPrimaryMethodUpdated)
|
||||
VisibilityUtil.getVisibilityModifier(currentPsiMethod.getModifierList())
|
||||
else
|
||||
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()
|
||||
val newJavaParameters = newParameterList.withIndex().map { pair ->
|
||||
return javaChangeInfo
|
||||
}
|
||||
|
||||
fun getJavaParameterInfos(currentPsiMethod: PsiMethod, newParameterList: List<JetParameterInfo>): MutableList<ParameterInfoImpl> {
|
||||
return newParameterList.withIndex().mapTo(ArrayList()) { pair ->
|
||||
val (i, info) = pair
|
||||
|
||||
val type = if (isPrimaryMethodUpdated)
|
||||
@@ -255,25 +269,66 @@ public class JetChangeInfo(
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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?
|
||||
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 {
|
||||
val method = getMethod() as PsiMethod
|
||||
@@ -305,7 +360,7 @@ public fun ChangeInfo.toJetChangeInfo(originalChangeSignatureDescriptor: JetMeth
|
||||
}
|
||||
else null
|
||||
|
||||
with(JetParameterInfo(functionDescriptor = functionDescriptor,
|
||||
with(JetParameterInfo(callableDescriptor = functionDescriptor,
|
||||
originalIndex = oldIndex,
|
||||
name = info.getName(),
|
||||
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 org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||
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.OverrideResolver
|
||||
|
||||
@@ -50,55 +54,64 @@ fun JetMethodDescriptor.modify(action: (JetMutableMethodDescriptor) -> Unit): Je
|
||||
}
|
||||
|
||||
public fun runChangeSignature(project: Project,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
callableDescriptor: CallableDescriptor,
|
||||
configuration: JetChangeSignatureConfiguration,
|
||||
bindingContext: BindingContext,
|
||||
defaultValueContext: PsiElement,
|
||||
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,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
callableDescriptor: CallableDescriptor,
|
||||
val configuration: JetChangeSignatureConfiguration,
|
||||
bindingContext: BindingContext,
|
||||
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>())
|
||||
|
||||
override fun forcePerformForSelectedFunctionOnly() = configuration.forcePerformForSelectedFunctionOnly()
|
||||
|
||||
override fun performRefactoring(descriptorsForChange: Collection<CallableDescriptor>) {
|
||||
assert (descriptorsForChange.all { it is FunctionDescriptor }) {
|
||||
"Function descriptors expected: " + descriptorsForChange.joinToString(separator = "\n")
|
||||
private fun runSilentRefactoring(descriptor: JetMethodDescriptor) {
|
||||
val commandName = commandName ?: ChangeSignatureHandler.REFACTORING_NAME
|
||||
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")
|
||||
val adjustedDescriptor = adjustDescriptor(descriptorsForChange as Collection<FunctionDescriptor>)
|
||||
if (adjustedDescriptor == null) return
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
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 (configuration.performSilently(affectedFunctions)
|
||||
|| ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
||||
JetChangeSignatureDialog.createRefactoringProcessorForSilentChangeSignature(
|
||||
project,
|
||||
commandName ?: ChangeSignatureHandler.REFACTORING_NAME,
|
||||
adjustedDescriptor,
|
||||
defaultValueContext
|
||||
).run()
|
||||
if (configuration.performSilently(affectedFunctions) || ApplicationManager.getApplication()!!.isUnitTestMode()) {
|
||||
runSilentRefactoring(adjustedDescriptor)
|
||||
}
|
||||
else {
|
||||
val dialog = JetChangeSignatureDialog(project, adjustedDescriptor, defaultValueContext, commandName)
|
||||
|
||||
dialog.show()
|
||||
runInteractiveRefactoring(adjustedDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
fun adjustDescriptor(descriptorsForSignatureChange: Collection<FunctionDescriptor>): JetMethodDescriptor? {
|
||||
fun adjustDescriptor(descriptorsForSignatureChange: Collection<CallableDescriptor>): JetMethodDescriptor? {
|
||||
val baseDescriptor = preferContainedInClass(descriptorsForSignatureChange)
|
||||
val functionDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, baseDescriptor)
|
||||
if (functionDeclaration == null) {
|
||||
@@ -114,7 +127,7 @@ public class JetChangeSignature(project: Project,
|
||||
return configuration.configure(originalDescriptor, bindingContext)
|
||||
}
|
||||
|
||||
private fun preferContainedInClass(descriptorsForSignatureChange: Collection<FunctionDescriptor>): FunctionDescriptor {
|
||||
private fun preferContainedInClass(descriptorsForSignatureChange: Collection<CallableDescriptor>): CallableDescriptor {
|
||||
for (descriptor in descriptorsForSignatureChange) {
|
||||
val containingDeclaration = descriptor.getContainingDeclaration()
|
||||
if (containingDeclaration is ClassDescriptor && containingDeclaration.getKind() != ClassKind.INTERFACE) {
|
||||
@@ -127,15 +140,22 @@ public class JetChangeSignature(project: Project,
|
||||
}
|
||||
|
||||
TestOnly public fun createChangeInfo(project: Project,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
callableDescriptor: CallableDescriptor,
|
||||
configuration: JetChangeSignatureConfiguration,
|
||||
bindingContext: BindingContext,
|
||||
defaultValueContext: PsiElement): JetChangeInfo? {
|
||||
val jetChangeSignature = JetChangeSignature(project, functionDescriptor, configuration, bindingContext, defaultValueContext, null)
|
||||
val declarations = OverrideResolver.getDeepestSuperDeclarations(functionDescriptor)
|
||||
val jetChangeSignature = JetChangeSignature(project, callableDescriptor, configuration, bindingContext, defaultValueContext, null)
|
||||
val declarations = if (callableDescriptor is CallableMemberDescriptor) {
|
||||
OverrideResolver.getDeepestSuperDeclarations(callableDescriptor)
|
||||
} else listOf(callableDescriptor)
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
+33
-24
@@ -23,6 +23,8 @@ import com.intellij.refactoring.changeSignature.OverriderUsageInfo
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
||||
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.impl.AnonymousFunctionDescriptor
|
||||
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.core.CollectingNameValidator
|
||||
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.psi.JetCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.JetClass
|
||||
import org.jetbrains.kotlin.psi.JetFunction
|
||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import java.util.Collections
|
||||
@@ -41,9 +47,9 @@ import java.util.HashSet
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
public class JetChangeSignatureData(
|
||||
override val baseDescriptor: FunctionDescriptor,
|
||||
override val baseDescriptor: CallableDescriptor,
|
||||
override val baseDeclaration: PsiElement,
|
||||
private val descriptorsForSignatureChange: Collection<FunctionDescriptor>
|
||||
private val descriptorsForSignatureChange: Collection<CallableDescriptor>
|
||||
) : JetMethodDescriptor {
|
||||
private val parameters: List<JetParameterInfo>
|
||||
override val receiver: JetParameterInfo?
|
||||
@@ -60,7 +66,7 @@ public class JetChangeSignatureData(
|
||||
.mapTo(receiver?.let{ arrayListOf(it) } ?: arrayListOf()) { parameterDescriptor ->
|
||||
val jetParameter = valueParameters?.get(parameterDescriptor.getIndex())
|
||||
JetParameterInfo(
|
||||
functionDescriptor = baseDescriptor,
|
||||
callableDescriptor = baseDescriptor,
|
||||
originalIndex = parameterDescriptor.getIndex(),
|
||||
name = parameterDescriptor.getName().asString(),
|
||||
type = parameterDescriptor.getType(),
|
||||
@@ -72,8 +78,8 @@ public class JetChangeSignatureData(
|
||||
}
|
||||
|
||||
private fun createReceiverInfoIfNeeded(): JetParameterInfo? {
|
||||
val function = baseDeclaration as? JetFunction ?: return null
|
||||
val bodyScope = function.getBodyExpression()?.let { it.analyze()[BindingContext.RESOLUTION_SCOPE, it] }
|
||||
val callable = baseDeclaration as? JetCallableDeclaration ?: return null
|
||||
val bodyScope = (callable as? JetFunction)?.getBodyExpression()?.let { it.analyze()[BindingContext.RESOLUTION_SCOPE, it] }
|
||||
val paramNames = baseDescriptor.getValueParameters().map { it.getName().asString() }
|
||||
val validator = bodyScope?.let { bodyScope ->
|
||||
CollectingNameValidator(paramNames) {
|
||||
@@ -83,34 +89,37 @@ public class JetChangeSignatureData(
|
||||
} ?: CollectingNameValidator(paramNames)
|
||||
val receiverType = baseDescriptor.getExtensionReceiverParameter()?.getType() ?: return null
|
||||
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 {
|
||||
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(baseDeclaration.getProject(), it)
|
||||
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 {
|
||||
primaryFunctions.first { it.getDeclaration() == baseDeclaration }
|
||||
override val originalPrimaryCallable: JetCallableDefinitionUsage<PsiElement> by Delegates.lazy {
|
||||
primaryCallables.first { it.getDeclaration() == baseDeclaration }
|
||||
}
|
||||
|
||||
override val affectedFunctions: Collection<UsageInfo> by Delegates.lazy {
|
||||
primaryFunctions + primaryFunctions.flatMapTo(HashSet<UsageInfo>()) { primaryFunction ->
|
||||
val primaryDeclaration = primaryFunction.getDeclaration() as? JetFunction
|
||||
val lightMethod = primaryDeclaration?.let { LightClassUtil.getLightClassMethod(it) }
|
||||
val overrides = lightMethod?.let { OverridingMethodsSearch.search(it).findAll() } ?: Collections.emptyList()
|
||||
overrides.map { method ->
|
||||
if (method is KotlinLightMethod) {
|
||||
val overridingDeclaration = method.getOrigin()
|
||||
val overridingDescriptor = overridingDeclaration?.resolveToDescriptor() as FunctionDescriptor
|
||||
JetFunctionDefinitionUsage<PsiElement>(overridingDeclaration, overridingDescriptor, primaryFunction, null)
|
||||
}
|
||||
else OverriderUsageInfo(method, lightMethod, true, true, true)
|
||||
}.filterNotNullTo(HashSet<UsageInfo>())
|
||||
override val affectedCallables: Collection<UsageInfo> by Delegates.lazy {
|
||||
primaryCallables + primaryCallables.flatMapTo(HashSet<UsageInfo>()) { primaryFunction ->
|
||||
val primaryDeclaration = primaryFunction.getDeclaration() as? JetCallableDeclaration
|
||||
val lightMethods = primaryDeclaration?.toLightMethods() ?: Collections.emptyList()
|
||||
lightMethods.flatMap { baseMethod ->
|
||||
OverridingMethodsSearch
|
||||
.search(baseMethod)
|
||||
.map { overridingMethod ->
|
||||
if (overridingMethod is KotlinLightMethod) {
|
||||
val overridingDeclaration = overridingMethod.namedUnwrappedElement as JetNamedDeclaration
|
||||
val overridingDescriptor = overridingDeclaration.resolveToDescriptor() as CallableDescriptor
|
||||
JetCallableDefinitionUsage<PsiElement>(overridingDeclaration, overridingDescriptor, primaryFunction, null)
|
||||
}
|
||||
else OverriderUsageInfo(overridingMethod, baseMethod, true, true, true)
|
||||
}.filterNotNullTo(HashSet<UsageInfo>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -416,7 +416,7 @@ public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
||||
getMethodName(),
|
||||
myDefaultValueContext
|
||||
);
|
||||
return changeInfo.getNewSignature(getMethodDescriptor().getOriginalPrimaryFunction());
|
||||
return changeInfo.getNewSignature(getMethodDescriptor().getOriginalPrimaryCallable());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+33
-33
@@ -34,10 +34,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.kotlin.asJava.AsJavaPackage;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils;
|
||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde;
|
||||
@@ -57,44 +54,44 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
@Nullable
|
||||
public static PsiElement findTargetForRefactoring(@NotNull PsiElement element) {
|
||||
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);
|
||||
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();
|
||||
if (elementParent instanceof JetNamedFunction && ((JetNamedFunction) 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 JetNamedFunction || elementParent instanceof JetClass || elementParent instanceof JetProperty)
|
||||
&& ((JetNamedDeclaration) elementParent).getNameIdentifier() == element) return elementParent;
|
||||
|
||||
if (elementParent instanceof JetSecondaryConstructor &&
|
||||
((JetSecondaryConstructor) elementParent).getConstructorKeyword() == element) return elementParent;
|
||||
|
||||
JetExpression calleeExpr;
|
||||
JetCallElement call = PsiTreeUtil.getParentOfType(element,
|
||||
JetCallExpression.class,
|
||||
JetDelegatorToSuperCall.class,
|
||||
JetConstructorDelegationCall.class);
|
||||
if (call == null) return null;
|
||||
|
||||
JetExpression receiverExpr = call.getCalleeExpression();
|
||||
if (receiverExpr instanceof JetConstructorCalleeExpression) {
|
||||
receiverExpr = ((JetConstructorCalleeExpression) receiverExpr).getConstructorReferenceExpression();
|
||||
if (call != null) {
|
||||
calleeExpr = call.getCalleeExpression();
|
||||
}
|
||||
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);
|
||||
if (jetElement == null) return null;
|
||||
|
||||
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;
|
||||
@@ -107,20 +104,20 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
@Nullable Editor editor
|
||||
) {
|
||||
BindingContext bindingContext = ResolvePackage.analyze(element, BodyResolveMode.FULL);
|
||||
|
||||
FunctionDescriptor functionDescriptor = findDescriptor(element, project, editor, bindingContext);
|
||||
if (functionDescriptor == null) {
|
||||
|
||||
CallableDescriptor callableDescriptor = findDescriptor(element, project, editor, bindingContext);
|
||||
if (callableDescriptor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (functionDescriptor instanceof JavaCallableMemberDescriptor) {
|
||||
PsiElement declaration = DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(project, functionDescriptor);
|
||||
assert declaration instanceof PsiMethod : "PsiMethod expected: " + functionDescriptor;
|
||||
if (callableDescriptor instanceof JavaCallableMemberDescriptor) {
|
||||
PsiElement declaration = DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(project, callableDescriptor);
|
||||
assert declaration instanceof PsiMethod : "PsiMethod expected: " + callableDescriptor;
|
||||
ChangeSignatureUtil.invokeChangeSignatureOn((PsiMethod) declaration, project);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TasksPackage.isDynamic(functionDescriptor)) {
|
||||
if (TasksPackage.isDynamic(callableDescriptor)) {
|
||||
if (editor != null) {
|
||||
CodeInsightUtils.showErrorHint(
|
||||
project,
|
||||
@@ -133,7 +130,7 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
runChangeSignature(project, functionDescriptor, emptyConfiguration(), bindingContext, context, null);
|
||||
runChangeSignature(project, callableDescriptor, emptyConfiguration(), bindingContext, context, null);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
@@ -208,7 +205,7 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FunctionDescriptor findDescriptor(
|
||||
public static CallableDescriptor findDescriptor(
|
||||
@NotNull PsiElement element,
|
||||
@NotNull Project project,
|
||||
@Nullable Editor editor,
|
||||
@@ -244,6 +241,9 @@ public class JetChangeSignatureHandler implements ChangeSignatureHandler {
|
||||
|
||||
return (FunctionDescriptor) descriptor;
|
||||
}
|
||||
else if (descriptor instanceof PropertyDescriptor) {
|
||||
return (PropertyDescriptor) descriptor;
|
||||
}
|
||||
else {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(JetRefactoringBundle.message(
|
||||
"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.psi.PsiElement;
|
||||
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.ui.ConflictsDialog;
|
||||
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.MultiMap;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.Pair;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetUsageInfo;
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinWrapperForJavaUsageInfos;
|
||||
@@ -62,10 +63,13 @@ public class JetChangeSignatureProcessor extends ChangeSignatureProcessorBase {
|
||||
protected UsageInfo[] findUsages() {
|
||||
List<UsageInfo> allUsages = new ArrayList<UsageInfo>();
|
||||
|
||||
JavaChangeInfo javaChangeInfo = getChangeInfo().getOrCreateJavaChangeInfo();
|
||||
if (javaChangeInfo != null) {
|
||||
UsageInfo[] javaUsages = new JavaChangeSignatureUsageProcessor().findUsages(javaChangeInfo);
|
||||
allUsages.add(new KotlinWrapperForJavaUsageInfos(javaUsages, getChangeInfo().getMethod()));
|
||||
List<JavaChangeInfo> javaChangeInfos = getChangeInfo().getOrCreateJavaChangeInfos();
|
||||
if (javaChangeInfos != null) {
|
||||
JavaChangeSignatureUsageProcessor javaProcessor = new JavaChangeSignatureUsageProcessor();
|
||||
for (JavaChangeInfo javaChangeInfo : javaChangeInfos) {
|
||||
UsageInfo[] javaUsages = javaProcessor.findUsages(javaChangeInfo);
|
||||
allUsages.add(new KotlinWrapperForJavaUsageInfos(javaChangeInfo, javaUsages, getChangeInfo().getMethod()));
|
||||
}
|
||||
}
|
||||
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.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
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.HashSet;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import jet.runtime.typeinfo.JetValueParameter;
|
||||
import kotlin.KotlinPackage;
|
||||
import kotlin.Unit;
|
||||
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.core.refactoring.RefactoringPackage;
|
||||
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.search.usagesSearch.UsagesSearchPackage;
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||
import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersPackage;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
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.model.ResolvedCall;
|
||||
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.scopes.JetScope;
|
||||
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.TypeUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsageProcessor {
|
||||
@Override
|
||||
@@ -104,8 +99,8 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
|
||||
private static void findAllMethodUsages(JetChangeInfo changeInfo, Set<UsageInfo> result) {
|
||||
for (UsageInfo functionUsageInfo : ChangeSignaturePackage.getAffectedFunctions(changeInfo)) {
|
||||
if (functionUsageInfo instanceof JetFunctionDefinitionUsage) {
|
||||
findOneMethodUsages((JetFunctionDefinitionUsage) functionUsageInfo, changeInfo, result);
|
||||
if (functionUsageInfo instanceof JetCallableDefinitionUsage) {
|
||||
findOneMethodUsages((JetCallableDefinitionUsage) functionUsageInfo, changeInfo, result);
|
||||
}
|
||||
else {
|
||||
result.add(functionUsageInfo);
|
||||
@@ -123,7 +118,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
JetCallElement callElement = PsiTreeUtil.getParentOfType(element, JetCallElement.class);
|
||||
JetExpression calleeExpression = callElement != null ? callElement.getCalleeExpression() : null;
|
||||
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(
|
||||
@NotNull JetFunctionDefinitionUsage<?> functionUsageInfo,
|
||||
@NotNull JetCallableDefinitionUsage<?> functionUsageInfo,
|
||||
final JetChangeInfo changeInfo,
|
||||
final Set<UsageInfo> result
|
||||
) {
|
||||
@@ -160,6 +155,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
if (parent instanceof JetConstructorCalleeExpression && parent.getParent() instanceof JetDelegatorToSuperCall)
|
||||
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)
|
||||
TextOccurrencesUtil.findNonCodeUsages(functionPsi, oldName, true, true, changeInfo.getNewName(), result);
|
||||
|
||||
List<JetParameter> oldParameters = functionPsi instanceof JetFunction
|
||||
? ((JetFunction) functionPsi).getValueParameters()
|
||||
: ((JetClass) functionPsi).getPrimaryConstructorParameters();
|
||||
List<JetParameter> oldParameters = PsiUtilPackage.getValueParameters((JetNamedDeclaration) functionPsi);
|
||||
|
||||
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
||||
|
||||
@@ -221,7 +217,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
}
|
||||
|
||||
private static void processInternalReferences(
|
||||
JetFunctionDefinitionUsage functionUsageInfo,
|
||||
JetCallableDefinitionUsage functionUsageInfo,
|
||||
JetTreeVisitor<BindingContext> visitor
|
||||
) {
|
||||
JetFunction jetFunction = (JetFunction) functionUsageInfo.getDeclaration();
|
||||
@@ -238,12 +234,12 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
}
|
||||
|
||||
private static void findOriginalReceiversUsages(
|
||||
@NotNull final JetFunctionDefinitionUsage<?> functionUsageInfo,
|
||||
@NotNull final JetCallableDefinitionUsage<?> functionUsageInfo,
|
||||
@NotNull final Set<UsageInfo> result,
|
||||
@NotNull final JetChangeInfo changeInfo
|
||||
) {
|
||||
final JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
||||
final FunctionDescriptor functionDescriptor = functionUsageInfo.getOriginalFunctionDescriptor();
|
||||
final CallableDescriptor callableDescriptor = functionUsageInfo.getOriginalCallableDescriptor();
|
||||
processInternalReferences(
|
||||
functionUsageInfo,
|
||||
new JetTreeVisitor<BindingContext>() {
|
||||
@@ -254,7 +250,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
if (originalReceiverInfo != null && !changeInfo.hasParameter(originalReceiverInfo)) 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();
|
||||
result.add(new JetParameterUsage(expression, originalReceiverInfo, functionUsageInfo));
|
||||
}
|
||||
@@ -270,7 +266,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
@NotNull ThisReceiver receiverValue
|
||||
) {
|
||||
DeclarationDescriptor targetDescriptor = receiverValue.getDeclarationDescriptor();
|
||||
if (targetDescriptor == functionDescriptor) {
|
||||
if (targetDescriptor == callableDescriptor) {
|
||||
assert originalReceiverInfo != null : "No original receiver info provided: " + functionUsageInfo.getDeclaration().getText();
|
||||
result.add(new JetImplicitThisToParameterUsage(callElement, originalReceiverInfo, functionUsageInfo));
|
||||
}
|
||||
@@ -407,7 +403,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
PsiElement function = info.getMethod();
|
||||
PsiElement element = function != null ? function : changeInfo.getContext();
|
||||
BindingContext bindingContext = ResolvePackage.analyze((JetElement) element, BodyResolveMode.FULL);
|
||||
FunctionDescriptor oldDescriptor = ChangeSignaturePackage.getOriginalBaseFunctionDescriptor(changeInfo);
|
||||
CallableDescriptor oldDescriptor = ChangeSignaturePackage.getOriginalBaseFunctionDescriptor(changeInfo);
|
||||
DeclarationDescriptor containingDeclaration = oldDescriptor.getContainingDeclaration();
|
||||
|
||||
JetScope parametersScope = null;
|
||||
@@ -416,17 +412,21 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
else if (function instanceof JetFunction)
|
||||
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);
|
||||
if (!kind.getIsConstructor() && functionScope != null && !info.getNewName().isEmpty()) {
|
||||
for (FunctionDescriptor conflict : functionScope.getFunctions(Name.identifier(info.getNewName()))) {
|
||||
if (!kind.getIsConstructor() && callableScope != null && !info.getNewName().isEmpty()) {
|
||||
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;
|
||||
|
||||
PsiElement conflictElement = DescriptorToSourceUtils.descriptorToDeclaration(conflict);
|
||||
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) + "'");
|
||||
break;
|
||||
}
|
||||
@@ -464,7 +464,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
|
||||
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
|
||||
JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
|
||||
if (function instanceof JetNamedFunction && newReceiverInfo != originalReceiverInfo) {
|
||||
if (function instanceof JetCallableDeclaration && newReceiverInfo != originalReceiverInfo) {
|
||||
findReceiverIntroducingConflicts(result, function, newReceiverInfo);
|
||||
findInternalExplicitReceiverConflicts(refUsages.get(), result, originalReceiverInfo);
|
||||
findThisLabelConflicts((JetChangeInfo) info, refUsages, result, changeInfo, function);
|
||||
@@ -525,10 +525,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
) {
|
||||
if (originalReceiverInfo == null) {
|
||||
for (UsageInfo usageInfo : usages) {
|
||||
if (!(usageInfo instanceof JetFunctionCallUsage)) continue;
|
||||
if (!(usageInfo instanceof JetFunctionCallUsage || usageInfo instanceof JetPropertyCallUsage)) continue;
|
||||
|
||||
JetFunctionCallUsage callUsage = (JetFunctionCallUsage) usageInfo;
|
||||
JetElement callElement = callUsage.getElement();
|
||||
JetElement callElement = (JetElement) usageInfo.getElement();
|
||||
if (callElement == null) continue;
|
||||
|
||||
PsiElement parent = callElement.getParent();
|
||||
@@ -546,7 +545,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
PsiElement callable,
|
||||
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(
|
||||
JetFileReferencesResolver.INSTANCE$.resolve((JetNamedFunction) callable, true, true),
|
||||
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>() {
|
||||
@Override
|
||||
public JetType fun(ValueParameterDescriptor descriptor) {
|
||||
@@ -710,26 +709,33 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
boolean isJavaMethodUsage = isJavaMethodUsage(usageInfo);
|
||||
|
||||
if (usageInfo instanceof KotlinWrapperForJavaUsageInfos) {
|
||||
JavaChangeInfo javaChangeInfo = ((JetChangeInfo) changeInfo).getOrCreateJavaChangeInfo();
|
||||
assert javaChangeInfo != null : "JavaChangeInfo not found: " + method.getText();
|
||||
UsageInfo[] javaUsageInfos = ((KotlinWrapperForJavaUsageInfos) usageInfo).getJavaUsageInfos();
|
||||
List<JavaChangeInfo> javaChangeInfos = ((JetChangeInfo) changeInfo).getOrCreateJavaChangeInfos();
|
||||
assert javaChangeInfos != null : "JavaChangeInfo not found: " + method.getText();
|
||||
|
||||
KotlinWrapperForJavaUsageInfos wrapperForJavaUsageInfos = (KotlinWrapperForJavaUsageInfos) usageInfo;
|
||||
UsageInfo[] javaUsageInfos = wrapperForJavaUsageInfos.getJavaUsageInfos();
|
||||
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) {
|
||||
if (usage instanceof OverriderUsageInfo && beforeMethodChange) continue;
|
||||
for (ChangeSignatureUsageProcessor processor : processors) {
|
||||
if (processor instanceof JetChangeSignatureUsageProcessor) continue;
|
||||
if (usage instanceof OverriderUsageInfo) {
|
||||
processor.processUsage(javaChangeInfo, usage, true, javaUsageInfos);
|
||||
NullabilityPropagator nullabilityPropagator = new NullabilityPropagator(javaChangeInfo.getMethod());
|
||||
|
||||
for (UsageInfo usage : javaUsageInfos) {
|
||||
if (usage instanceof OverriderUsageInfo && beforeMethodChange) continue;
|
||||
for (ChangeSignatureUsageProcessor processor : processors) {
|
||||
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 (overridingMethod != null && !(overridingMethod instanceof KotlinLightMethod)) {
|
||||
nullabilityPropagator.processMethod(overridingMethod);
|
||||
if (usage instanceof OverriderUsageInfo) {
|
||||
PsiMethod overridingMethod = ((OverriderUsageInfo) usage).getOverridingMethod();
|
||||
if (overridingMethod != null && !(overridingMethod instanceof KotlinLightMethod)) {
|
||||
nullabilityPropagator.processMethod(overridingMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,7 +798,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
if (!(changeInfo instanceof JetChangeInfo)) return false;
|
||||
|
||||
JetChangeInfo jetChangeInfo = (JetChangeInfo) changeInfo;
|
||||
for (JetFunctionDefinitionUsage primaryFunction : jetChangeInfo.getMethodDescriptor().getPrimaryFunctions()) {
|
||||
for (JetCallableDefinitionUsage primaryFunction : jetChangeInfo.getMethodDescriptor().getPrimaryCallables()) {
|
||||
primaryFunction.processUsage(jetChangeInfo, primaryFunction.getDeclaration());
|
||||
}
|
||||
jetChangeInfo.primaryMethodUpdated();
|
||||
|
||||
+7
-7
@@ -19,10 +19,10 @@ package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.refactoring.changeSignature.MethodDescriptor
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.JetFunctionDefinitionUsage
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
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
|
||||
|
||||
public trait JetMethodDescriptor : MethodDescriptor<JetParameterInfo, Visibility> {
|
||||
@@ -42,11 +42,11 @@ public trait JetMethodDescriptor : MethodDescriptor<JetParameterInfo, Visibility
|
||||
}
|
||||
|
||||
val baseDeclaration: PsiElement
|
||||
val baseDescriptor: FunctionDescriptor
|
||||
val baseDescriptor: CallableDescriptor
|
||||
|
||||
val originalPrimaryFunction: JetFunctionDefinitionUsage<PsiElement>
|
||||
val primaryFunctions: Collection<JetFunctionDefinitionUsage<PsiElement>>
|
||||
val affectedFunctions: Collection<UsageInfo>
|
||||
val originalPrimaryCallable: JetCallableDefinitionUsage<PsiElement>
|
||||
val primaryCallables: Collection<JetCallableDefinitionUsage<PsiElement>>
|
||||
val affectedCallables: Collection<UsageInfo>
|
||||
|
||||
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.idea.caches.resolve.analyze
|
||||
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.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.types.JetType
|
||||
import java.util.LinkedHashMap
|
||||
|
||||
public class JetParameterInfo(
|
||||
val functionDescriptor: FunctionDescriptor,
|
||||
val callableDescriptor: CallableDescriptor,
|
||||
val originalIndex: Int = -1,
|
||||
private var name: String,
|
||||
type: JetType? = null,
|
||||
@@ -61,7 +61,7 @@ public class JetParameterInfo(
|
||||
object : JetTreeVisitorVoid() {
|
||||
private fun selfParameterOrNull(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
|
||||
return if (parameter is ValueParameterDescriptor &&
|
||||
compareDescriptors(project, parameter.getContainingDeclaration(), functionDescriptor)) {
|
||||
compareDescriptors(project, parameter.getContainingDeclaration(), callableDescriptor)) {
|
||||
parameter
|
||||
} else null
|
||||
}
|
||||
@@ -69,12 +69,12 @@ public class JetParameterInfo(
|
||||
private fun selfReceiverOrNull(receiverDescriptor: DeclarationDescriptor?): DeclarationDescriptor? {
|
||||
if (compareDescriptors(project,
|
||||
receiverDescriptor,
|
||||
functionDescriptor.getExtensionReceiverParameter()?.getContainingDeclaration())) {
|
||||
callableDescriptor.getExtensionReceiverParameter()?.getContainingDeclaration())) {
|
||||
return receiverDescriptor
|
||||
}
|
||||
if (compareDescriptors(project,
|
||||
receiverDescriptor,
|
||||
functionDescriptor.getDispatchReceiverParameter()?.getContainingDeclaration())) {
|
||||
callableDescriptor.getDispatchReceiverParameter()?.getContainingDeclaration())) {
|
||||
return receiverDescriptor
|
||||
}
|
||||
return null
|
||||
@@ -93,7 +93,7 @@ public class JetParameterInfo(
|
||||
val descriptor = ref.resolveToDescriptors(context).singleOrNull()
|
||||
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
|
||||
return parameter?.let { selfParameterOrNull(context[BindingContext.VALUE_PARAMETER, it]) }
|
||||
}
|
||||
@@ -149,20 +149,20 @@ public class JetParameterInfo(
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
public fun renderType(parameterIndex: Int, inheritedFunction: JetFunctionDefinitionUsage<*>): String {
|
||||
val typeSubstitutor = inheritedFunction.getOrCreateTypeSubstitutor() ?: return currentTypeText
|
||||
val currentBaseFunction = inheritedFunction.getBaseFunction().getCurrentFunctionDescriptor() ?: return currentTypeText
|
||||
public fun renderType(parameterIndex: Int, inheritedCallable: JetCallableDefinitionUsage<*>): String {
|
||||
val typeSubstitutor = inheritedCallable.getOrCreateTypeSubstitutor() ?: return currentTypeText
|
||||
val currentBaseFunction = inheritedCallable.getBaseFunction().getCurrentCallableDescriptor() ?: return currentTypeText
|
||||
val parameterType = currentBaseFunction.getValueParameters().get(parameterIndex).getType()
|
||||
return parameterType.renderTypeWithSubstitution(typeSubstitutor, currentTypeText, true)
|
||||
}
|
||||
|
||||
public fun getInheritedName(inheritedFunction: JetFunctionDefinitionUsage<*>): String {
|
||||
if (!inheritedFunction.isInherited()) return name
|
||||
public fun getInheritedName(inheritedCallable: JetCallableDefinitionUsage<*>): String {
|
||||
if (!inheritedCallable.isInherited()) return name
|
||||
|
||||
val baseFunction = inheritedFunction.getBaseFunction()
|
||||
val baseFunctionDescriptor = baseFunction.getOriginalFunctionDescriptor()
|
||||
val baseFunction = inheritedCallable.getBaseFunction()
|
||||
val baseFunctionDescriptor = baseFunction.getOriginalCallableDescriptor()
|
||||
|
||||
val inheritedFunctionDescriptor = inheritedFunction.getOriginalFunctionDescriptor()
|
||||
val inheritedFunctionDescriptor = inheritedCallable.getOriginalCallableDescriptor()
|
||||
val inheritedParameterDescriptors = inheritedFunctionDescriptor.getValueParameters()
|
||||
if (originalIndex < 0
|
||||
|| originalIndex >= baseFunctionDescriptor.getValueParameters().size()
|
||||
@@ -177,18 +177,18 @@ public class JetParameterInfo(
|
||||
}
|
||||
}
|
||||
|
||||
public fun requiresExplicitType(inheritedFunction: JetFunctionDefinitionUsage<PsiElement>): Boolean {
|
||||
val inheritedFunctionDescriptor = inheritedFunction.getOriginalFunctionDescriptor()
|
||||
public fun requiresExplicitType(inheritedCallable: JetCallableDefinitionUsage<PsiElement>): Boolean {
|
||||
val inheritedFunctionDescriptor = inheritedCallable.getOriginalCallableDescriptor()
|
||||
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 parameter = DescriptorToSourceUtils.descriptorToDeclaration(inheritedParameterDescriptor) as? JetParameter ?: return false
|
||||
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()
|
||||
|
||||
if (modifierList != null) {
|
||||
@@ -199,13 +199,13 @@ public class JetParameterInfo(
|
||||
buffer.append(valOrVar).append(' ')
|
||||
}
|
||||
|
||||
buffer.append(getInheritedName(inheritedFunction))
|
||||
buffer.append(getInheritedName(inheritedCallable))
|
||||
|
||||
if (requiresExplicitType(inheritedFunction)) {
|
||||
buffer.append(": ").append(renderType(parameterIndex, inheritedFunction))
|
||||
if (requiresExplicitType(inheritedCallable)) {
|
||||
buffer.append(": ").append(renderType(parameterIndex, inheritedCallable))
|
||||
}
|
||||
|
||||
if (!inheritedFunction.isInherited()) {
|
||||
if (!inheritedCallable.isInherited()) {
|
||||
defaultValueForParameter?.let { buffer.append(" = ").append(it.getText()) }
|
||||
}
|
||||
|
||||
|
||||
@@ -16,18 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
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.refactoring.changeSignature.usages.JetCallableDefinitionUsage
|
||||
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>? {
|
||||
val substitutedType = TypeCheckingProcedure.findCorrespondingSupertype(derivedType, baseType) ?: return null
|
||||
@@ -40,15 +35,15 @@ private fun getTypeSubstitution(baseType: JetType, derivedType: JetType): Linked
|
||||
return substitution
|
||||
}
|
||||
|
||||
private fun getFunctionSubstitution(
|
||||
baseFunction: FunctionDescriptor,
|
||||
derivedFunction: FunctionDescriptor
|
||||
private fun getCallableSubstitution(
|
||||
baseCallable: CallableDescriptor,
|
||||
derivedCallable: CallableDescriptor
|
||||
): MutableMap<TypeConstructor, TypeProjection>? {
|
||||
val baseClass = baseFunction.getContainingDeclaration() as? ClassDescriptor ?: return null
|
||||
val derivedClass = derivedFunction.getContainingDeclaration() as? ClassDescriptor ?: return null
|
||||
val baseClass = baseCallable.getContainingDeclaration() as? ClassDescriptor ?: return null
|
||||
val derivedClass = derivedCallable.getContainingDeclaration() as? ClassDescriptor ?: 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())
|
||||
}
|
||||
|
||||
@@ -59,15 +54,15 @@ fun getTypeSubstitutor(baseType: JetType, derivedType: JetType): TypeSubstitutor
|
||||
return getTypeSubstitution(baseType, derivedType)?.let { TypeSubstitutor.create(it) }
|
||||
}
|
||||
|
||||
fun getFunctionSubstitutor(
|
||||
baseFunction: JetFunctionDefinitionUsage<*>,
|
||||
derivedFunction: JetFunctionDefinitionUsage<*>
|
||||
fun getCallableSubstitutor(
|
||||
baseFunction: JetCallableDefinitionUsage<*>,
|
||||
derivedCallable: JetCallableDefinitionUsage<*>
|
||||
): TypeSubstitutor? {
|
||||
val currentBaseFunction = baseFunction.getCurrentFunctionDescriptor()
|
||||
val currentDerivedFunction = derivedFunction.getCurrentFunctionDescriptor()
|
||||
val currentBaseFunction = baseFunction.getCurrentCallableDescriptor()
|
||||
val currentDerivedFunction = derivedCallable.getCurrentCallableDescriptor()
|
||||
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 {
|
||||
|
||||
+2
-2
@@ -35,10 +35,10 @@ public class DeferredJavaMethodOverrideOrSAMUsage(
|
||||
): JavaMethodDeferredKotlinUsage<JetFunction>(function) {
|
||||
override fun resolve(javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetFunction> {
|
||||
return object : JavaMethodKotlinUsageWithDelegate<JetFunction>(function, javaMethodChangeInfo) {
|
||||
override val delegateUsage = JetFunctionDefinitionUsage(
|
||||
override val delegateUsage = JetCallableDefinitionUsage(
|
||||
function,
|
||||
functionDescriptor,
|
||||
javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction,
|
||||
javaMethodChangeInfo.methodDescriptor.originalPrimaryCallable,
|
||||
samCallType
|
||||
)
|
||||
}
|
||||
|
||||
+3
-3
@@ -34,7 +34,7 @@ public abstract class JavaMethodKotlinUsageWithDelegate<T: PsiElement>(
|
||||
public class JavaMethodKotlinCallUsage(
|
||||
callElement: JetCallElement,
|
||||
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(
|
||||
@@ -42,10 +42,10 @@ public class JavaMethodKotlinDerivedDefinitionUsage(
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
javaMethodChangeInfo: JetChangeInfo): JavaMethodKotlinUsageWithDelegate<JetFunction>(function, javaMethodChangeInfo) {
|
||||
@suppress("CAST_NEVER_SUCCEEDS")
|
||||
override protected val delegateUsage = JetFunctionDefinitionUsage(
|
||||
override protected val delegateUsage = JetCallableDefinitionUsage(
|
||||
psiElement,
|
||||
functionDescriptor,
|
||||
javaMethodChangeInfo.methodDescriptor.originalPrimaryFunction,
|
||||
javaMethodChangeInfo.methodDescriptor.originalPrimaryCallable,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
+81
-67
@@ -26,9 +26,9 @@ import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||
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.lexer.JetModifierKeywordToken;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilPackage;
|
||||
import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersPackage;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
@@ -52,14 +53,14 @@ import java.util.List;
|
||||
|
||||
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
|
||||
private final FunctionDescriptor originalFunctionDescriptor;
|
||||
private final CallableDescriptor originalCallableDescriptor;
|
||||
|
||||
private FunctionDescriptor currentFunctionDescriptor;
|
||||
private CallableDescriptor currentCallableDescriptor;
|
||||
|
||||
@NotNull
|
||||
private final JetFunctionDefinitionUsage<? extends PsiElement> baseFunction;
|
||||
private final JetCallableDefinitionUsage<? extends PsiElement> baseFunction;
|
||||
|
||||
private final boolean hasExpectedType;
|
||||
|
||||
@@ -69,24 +70,25 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
@Nullable
|
||||
private TypeSubstitutor typeSubstitutor;
|
||||
|
||||
public JetFunctionDefinitionUsage(
|
||||
public JetCallableDefinitionUsage(
|
||||
@NotNull T function,
|
||||
@NotNull FunctionDescriptor originalFunctionDescriptor,
|
||||
@Nullable JetFunctionDefinitionUsage<PsiElement> baseFunction,
|
||||
@Nullable JetType samCallType) {
|
||||
@NotNull CallableDescriptor originalCallableDescriptor,
|
||||
@Nullable JetCallableDefinitionUsage<PsiElement> baseFunction,
|
||||
@Nullable JetType samCallType
|
||||
) {
|
||||
super(function);
|
||||
this.originalFunctionDescriptor = originalFunctionDescriptor;
|
||||
this.originalCallableDescriptor = originalCallableDescriptor;
|
||||
this.baseFunction = baseFunction != null ? baseFunction : this;
|
||||
this.hasExpectedType = checkIfHasExpectedType(originalFunctionDescriptor, isInherited());
|
||||
this.hasExpectedType = checkIfHasExpectedType(originalCallableDescriptor, isInherited());
|
||||
this.samCallType = samCallType;
|
||||
}
|
||||
|
||||
private static boolean checkIfHasExpectedType(@NotNull FunctionDescriptor functionDescriptor, boolean isInherited) {
|
||||
if (!(functionDescriptor instanceof AnonymousFunctionDescriptor && isInherited)) return false;
|
||||
private static boolean checkIfHasExpectedType(@NotNull CallableDescriptor callableDescriptor, boolean isInherited) {
|
||||
if (!(callableDescriptor instanceof AnonymousFunctionDescriptor && isInherited)) return false;
|
||||
|
||||
JetFunctionLiteral functionLiteral =
|
||||
(JetFunctionLiteral) DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);
|
||||
assert functionLiteral != null : "No declaration found for " + functionDescriptor;
|
||||
(JetFunctionLiteral) DescriptorToSourceUtils.descriptorToDeclaration(callableDescriptor);
|
||||
assert functionLiteral != null : "No declaration found for " + callableDescriptor;
|
||||
|
||||
PsiElement parent = functionLiteral.getParent();
|
||||
if (!(parent instanceof JetFunctionLiteralExpression)) return false;
|
||||
@@ -96,7 +98,7 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetFunctionDefinitionUsage getBaseFunction() {
|
||||
public JetCallableDefinitionUsage getBaseFunction() {
|
||||
return baseFunction;
|
||||
}
|
||||
|
||||
@@ -112,10 +114,10 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
|
||||
if (typeSubstitutor == null) {
|
||||
if (samCallType == null) {
|
||||
typeSubstitutor = ChangeSignaturePackage.getFunctionSubstitutor(baseFunction, this);
|
||||
typeSubstitutor = ChangeSignaturePackage.getCallableSubstitutor(baseFunction, this);
|
||||
}
|
||||
else {
|
||||
DeclarationDescriptor currentBaseDescriptor = baseFunction.getCurrentFunctionDescriptor();
|
||||
DeclarationDescriptor currentBaseDescriptor = baseFunction.getCurrentCallableDescriptor();
|
||||
DeclarationDescriptor classDescriptor = currentBaseDescriptor != null
|
||||
? currentBaseDescriptor.getContainingDeclaration()
|
||||
: null;
|
||||
@@ -140,71 +142,51 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final FunctionDescriptor getOriginalFunctionDescriptor() {
|
||||
return originalFunctionDescriptor;
|
||||
public final CallableDescriptor getOriginalCallableDescriptor() {
|
||||
return originalCallableDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final FunctionDescriptor getCurrentFunctionDescriptor() {
|
||||
if (currentFunctionDescriptor == null) {
|
||||
public final CallableDescriptor getCurrentCallableDescriptor() {
|
||||
if (currentCallableDescriptor == null) {
|
||||
PsiElement element = getDeclaration();
|
||||
|
||||
if (element instanceof JetFunction) {
|
||||
currentFunctionDescriptor = (FunctionDescriptor) ResolvePackage.resolveToDescriptor((JetFunction) element);
|
||||
if (element instanceof JetFunction || element instanceof JetProperty) {
|
||||
currentCallableDescriptor = (CallableDescriptor) ResolvePackage.resolveToDescriptor((JetDeclaration) element);
|
||||
}
|
||||
else if (element instanceof JetClass) {
|
||||
currentFunctionDescriptor = ((ClassDescriptor) ResolvePackage.resolveToDescriptor((JetClass) element)).getUnsubstitutedPrimaryConstructor();
|
||||
currentCallableDescriptor = ((ClassDescriptor) ResolvePackage.resolveToDescriptor((JetClass) element)).getUnsubstitutedPrimaryConstructor();
|
||||
}
|
||||
else if (element instanceof PsiMethod) {
|
||||
currentFunctionDescriptor = ResolvePackage.getJavaMethodDescriptor((PsiMethod) element);
|
||||
currentCallableDescriptor = ResolvePackage.getJavaMethodDescriptor((PsiMethod) element);
|
||||
}
|
||||
}
|
||||
return currentFunctionDescriptor;
|
||||
return currentCallableDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processUsage(JetChangeInfo changeInfo, PsiElement element) {
|
||||
JetParameterList parameterList;
|
||||
if (!(element instanceof JetNamedDeclaration)) return true;
|
||||
|
||||
JetPsiFactory psiFactory = JetPsiFactory(element.getProject());
|
||||
if (element instanceof JetFunction) {
|
||||
JetFunction function = (JetFunction) element;
|
||||
parameterList = function.getValueParameterList();
|
||||
|
||||
if (changeInfo.isNameChanged()) {
|
||||
PsiElement identifier = function.getNameIdentifier();
|
||||
if (changeInfo.isNameChanged()) {
|
||||
PsiElement identifier = ((JetCallableDeclaration) element).getNameIdentifier();
|
||||
|
||||
if (identifier != null) {
|
||||
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
|
||||
);
|
||||
}
|
||||
if (identifier != null) {
|
||||
identifier.replace(psiFactory.createIdentifier(changeInfo.getNewName()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
parameterList = ((JetClass) element).getPrimaryConstructorParameterList();
|
||||
}
|
||||
|
||||
changeReturnTypeIfNeeded(changeInfo, element);
|
||||
|
||||
JetParameterList parameterList = PsiUtilPackage.getValueParameterList((JetNamedDeclaration) element);
|
||||
|
||||
if (changeInfo.isParameterSetOrOrderChanged()) {
|
||||
processParameterListWithStructuralChanges(changeInfo, element, parameterList, psiFactory);
|
||||
}
|
||||
else if (parameterList != null) {
|
||||
int paramIndex = originalFunctionDescriptor.getExtensionReceiverParameter() != null ? 1 : 0;
|
||||
int paramIndex = originalCallableDescriptor.getExtensionReceiverParameter() != null ? 1 : 0;
|
||||
|
||||
for (JetParameter parameter : parameterList.getParameters()) {
|
||||
JetParameterInfo parameterInfo = changeInfo.getNewParameters()[paramIndex];
|
||||
@@ -215,11 +197,11 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
ShortenPackage.addToShorteningWaitSet(parameterList, Options.DEFAULT);
|
||||
}
|
||||
|
||||
if (element instanceof JetFunction && changeInfo.isReceiverTypeChanged()) {
|
||||
if (element instanceof JetCallableDeclaration && changeInfo.isReceiverTypeChanged()) {
|
||||
//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 newReceiverTypeRef = TypeRefHelpersPackage.setReceiverTypeReference((JetFunction) element, receiverTypeRef);
|
||||
JetTypeReference newReceiverTypeRef = TypeRefHelpersPackage.setReceiverTypeReference((JetCallableDeclaration) element, receiverTypeRef);
|
||||
if (newReceiverTypeRef != null) {
|
||||
ShortenPackage.addToShorteningWaitSet(newReceiverTypeRef, ShortenReferences.Options.DEFAULT);
|
||||
}
|
||||
@@ -232,6 +214,36 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
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(
|
||||
JetChangeInfo changeInfo,
|
||||
PsiElement element,
|
||||
@@ -256,14 +268,14 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
}
|
||||
else {
|
||||
newParameterList = psiFactory.createFunctionLiteralParameterList(changeInfo.getNewParametersSignature(
|
||||
(JetFunctionDefinitionUsage<PsiElement>) this)
|
||||
(JetCallableDefinitionUsage<PsiElement>) this)
|
||||
);
|
||||
canReplaceEntireList = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (!(element instanceof JetProperty)) {
|
||||
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) {
|
||||
JetModifierKeywordToken newVisibilityToken = JetRefactoringUtil.getVisibilityToken(changeInfo.getNewVisibility());
|
||||
|
||||
if (element instanceof JetFunction) {
|
||||
((JetFunction)element).addModifier(newVisibilityToken);
|
||||
if (element instanceof JetCallableDeclaration) {
|
||||
((JetCallableDeclaration)element).addModifier(newVisibilityToken);
|
||||
}
|
||||
else {
|
||||
else if (element instanceof JetClass) {
|
||||
JetPrimaryConstructor constructor = ((JetClass) element).getPrimaryConstructor();
|
||||
assert constructor != null : "Primary constructor should be created before changing visibility";
|
||||
constructor.addModifier(newVisibilityToken);
|
||||
}
|
||||
else throw new AssertionError("Invalid element: " + PsiUtilPackage.getElementTextWithContext(element));
|
||||
}
|
||||
|
||||
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) {
|
||||
PsiElement firstChild = parameter.getFirstChild();
|
||||
//noinspection ConstantConditions
|
||||
parameter.addBefore(valOrVar.createKeyword(psiFactory), firstChild);
|
||||
parameter.addBefore(psiFactory.createWhiteSpace(), firstChild);
|
||||
}
|
||||
@@ -378,7 +392,7 @@ public class JetFunctionDefinitionUsage<T extends PsiElement> extends JetUsageIn
|
||||
|
||||
if (identifier != null) {
|
||||
//noinspection unchecked
|
||||
String newName = parameterInfo.getInheritedName((JetFunctionDefinitionUsage<PsiElement>) this);
|
||||
String newName = parameterInfo.getInheritedName(this);
|
||||
identifier.replace(psiFactory.createIdentifier(newName));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ public class JetConstructorDelegationCallUsage(
|
||||
call: JetConstructorDelegationCall,
|
||||
changeInfo: JetChangeInfo
|
||||
) : 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 {
|
||||
val isThisCall = element.isCallToThis()
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class JetEnumEntryWithoutSuperCallUsage(enumEntry: JetEnumEntry) : JetUsa
|
||||
) as JetDelegatorToSuperCall
|
||||
element.addBefore(psiFactory.createColon(), delegatorToSuperCall)
|
||||
|
||||
return JetFunctionCallUsage(delegatorToSuperCall, changeInfo.methodDescriptor.originalPrimaryFunction)
|
||||
return JetFunctionCallUsage(delegatorToSuperCall, changeInfo.methodDescriptor.originalPrimaryCallable)
|
||||
.processUsage(changeInfo, delegatorToSuperCall)
|
||||
}
|
||||
|
||||
|
||||
+67
-10
@@ -29,6 +29,7 @@ import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.PropertyCodegen;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||
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.introduceVariable.KotlinIntroduceVariableHandler;
|
||||
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.resolve.BindingContext;
|
||||
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 final JetFunctionDefinitionUsage<?> callee;
|
||||
private final JetCallableDefinitionUsage<?> callee;
|
||||
private final BindingContext context;
|
||||
private final ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
||||
|
||||
public JetFunctionCallUsage(@NotNull JetCallElement element, JetFunctionDefinitionUsage callee) {
|
||||
public JetFunctionCallUsage(@NotNull JetCallElement element, JetCallableDefinitionUsage callee) {
|
||||
super(element);
|
||||
this.callee = callee;
|
||||
this.context = ResolvePackage.analyze(element, BodyResolveMode.FULL);
|
||||
@@ -88,13 +92,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
|
||||
@Override
|
||||
public boolean processUsage(JetChangeInfo changeInfo, JetCallElement element) {
|
||||
if (changeInfo.isNameChanged()) {
|
||||
JetExpression callee = element.getCalleeExpression();
|
||||
|
||||
if (callee instanceof JetSimpleNameExpression) {
|
||||
callee.replace(JetPsiFactory(getProject()).createSimpleName(changeInfo.getNewName()));
|
||||
}
|
||||
}
|
||||
changeNameIfNeeded(changeInfo, element);
|
||||
|
||||
if (element.getValueArgumentList() != null) {
|
||||
if (changeInfo.isParameterSetOrOrderChanged()) {
|
||||
@@ -118,6 +116,27 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
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
|
||||
private JetExpression getReceiverExpressionIfMatched(
|
||||
@NotNull ReceiverValue receiverValue,
|
||||
@@ -288,6 +307,11 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
assert arguments != null : "Argument list is expected: " + element.getText();
|
||||
List<? extends ValueArgument> oldArguments = element.getValueArguments();
|
||||
|
||||
if (isPropertyJavaUsage()) {
|
||||
updateJavaPropertyCall(changeInfo, element);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isNamedCall = oldArguments.size() > 1 && oldArguments.get(0).isNamed();
|
||||
StringBuilder parametersBuilder = new StringBuilder("(");
|
||||
boolean isFirst = true;
|
||||
@@ -388,7 +412,8 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||
|
||||
//TODO: this is not correct!
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
private static JetExpression getReceiverExpression(@NotNull ReceiverValue receiver, @NotNull JetPsiFactory psiFactory) {
|
||||
if (receiver instanceof ExpressionReceiver) {
|
||||
|
||||
+2
-2
@@ -44,9 +44,9 @@ public abstract class JetImplicitReceiverUsage(callElement: JetElement): JetUsag
|
||||
public class JetImplicitThisToParameterUsage(
|
||||
callElement: JetElement,
|
||||
val parameterInfo: JetParameterInfo,
|
||||
val containingFunction: JetFunctionDefinitionUsage<*>
|
||||
val containingCallable: JetCallableDefinitionUsage<*>
|
||||
): JetImplicitReceiverUsage(callElement) {
|
||||
override fun getNewReceiverText(): String = parameterInfo.getInheritedName(containingFunction)
|
||||
override fun getNewReceiverText(): String = parameterInfo.getInheritedName(containingCallable)
|
||||
|
||||
override fun processReplacedElement(element: JetElement) {
|
||||
element.addToShorteningWaitSet(Options(removeThisLabels = true))
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ public abstract class JetExplicitReferenceUsage<T: JetElement>(element: T) : Jet
|
||||
public class JetParameterUsage(
|
||||
element: JetElement,
|
||||
private val parameterInfo: JetParameterInfo,
|
||||
val containingFunction: JetFunctionDefinitionUsage<*>
|
||||
val containingCallable: JetCallableDefinitionUsage<*>
|
||||
) : JetExplicitReferenceUsage<JetElement>(element) {
|
||||
override fun processReplacedElement(element: JetElement) {
|
||||
val qualifiedExpression = element.getParent() as? JetQualifiedExpression
|
||||
@@ -56,7 +56,7 @@ public class JetParameterUsage(
|
||||
|
||||
override fun getReplacementText(changeInfo: JetChangeInfo): String =
|
||||
if (changeInfo.receiverParameterInfo != parameterInfo) {
|
||||
parameterInfo.getInheritedName(containingFunction)
|
||||
parameterInfo.getInheritedName(containingCallable)
|
||||
} 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
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.refactoring.changeSignature.JavaChangeInfo
|
||||
import com.intellij.usageView.UsageInfo
|
||||
|
||||
public class KotlinWrapperForJavaUsageInfos(
|
||||
val javaChangeInfo: JavaChangeInfo,
|
||||
val javaUsageInfos: Array<UsageInfo>,
|
||||
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.core.refactoring.isMultiLine
|
||||
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.KotlinParameterTablePanel
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||
@@ -233,18 +234,9 @@ public class KotlinIntroduceParameterDialog private constructor(
|
||||
override fun createCenterPanel() = null
|
||||
|
||||
override fun canRun() {
|
||||
fun validateElement(e: PsiElement, errorMessage: String) {
|
||||
try {
|
||||
AnalyzingUtils.checkForSyntacticErrors(e)
|
||||
}
|
||||
catch(e: Exception) {
|
||||
throw ConfigurationException(errorMessage)
|
||||
}
|
||||
}
|
||||
|
||||
val psiFactory = JetPsiFactory(myProject)
|
||||
validateElement(psiFactory.createType(nameField.getEnteredName()), "Invalid parameter name")
|
||||
validateElement(psiFactory.createType(typeField.getEnteredName()), "Invalid parameter type")
|
||||
psiFactory.createSimpleName(nameField.getEnteredName()).validateElement("Invalid parameter name")
|
||||
psiFactory.createType(typeField.getEnteredName()).validateElement("Invalid parameter type")
|
||||
}
|
||||
|
||||
override fun doAction() {
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ fun IntroduceParameterDescriptor.performRefactoring() {
|
||||
.forEach { methodDescriptor.removeParameter(it) }
|
||||
}
|
||||
|
||||
val parameterInfo = JetParameterInfo(functionDescriptor = callableDescriptor,
|
||||
val parameterInfo = JetParameterInfo(callableDescriptor = callableDescriptor,
|
||||
name = newParameterName,
|
||||
defaultValueForCall = if (withDefaultValue) null else newArgumentValue,
|
||||
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
|
||||
val defaultValueForCall = (data.getParameterInitializer().getExpression()!! as? PsiExpression)?.let { it.j2k() }
|
||||
changeInfo.addParameter(JetParameterInfo(functionDescriptor = psiMethodDescriptor,
|
||||
changeInfo.addParameter(JetParameterInfo(callableDescriptor = psiMethodDescriptor,
|
||||
name = data.getParameterName(),
|
||||
type = KotlinBuiltIns.getInstance().getAnyType(),
|
||||
defaultValueForCall = defaultValueForCall))
|
||||
@@ -100,7 +100,7 @@ public class KotlinIntroduceParameterMethodUsageProcessor : IntroduceParameterMe
|
||||
.map { it.unwrapped }
|
||||
.filterIsInstance<JetFunction>()
|
||||
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>)
|
||||
}
|
||||
else {
|
||||
JetFunctionCallUsage(callElement, changeInfo.methodDescriptor.originalPrimaryFunction)
|
||||
JetFunctionCallUsage(callElement, changeInfo.methodDescriptor.originalPrimaryCallable)
|
||||
}
|
||||
return delegateUsage.processUsage(changeInfo, callElement)
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
|
||||
import com.intellij.openapi.options.ConfigurationException
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.refactoring.listeners.RefactoringEventData
|
||||
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.JavaToKotlinConverter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||
|
||||
fun <T: Any> PsiElement.getAndRemoveCopyableUserData(key: Key<T>): T? {
|
||||
val data = getCopyableUserData(key)
|
||||
@@ -604,4 +606,14 @@ public fun (() -> Any).runRefactoringWithPostprocessing(
|
||||
}
|
||||
})
|
||||
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.Nullable;
|
||||
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.idea.caches.resolve.ResolvePackage;
|
||||
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
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
@@ -1039,11 +1100,11 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
|
||||
PsiElement context = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
assertNotNull(context);
|
||||
|
||||
FunctionDescriptor functionDescriptor = JetChangeSignatureHandler.findDescriptor(element, project, editor, bindingContext);
|
||||
assertNotNull(functionDescriptor);
|
||||
CallableDescriptor callableDescriptor = JetChangeSignatureHandler.findDescriptor(element, project, editor, bindingContext);
|
||||
assertNotNull(callableDescriptor);
|
||||
|
||||
return ChangeSignaturePackage.createChangeInfo(
|
||||
project, functionDescriptor, JetChangeSignatureHandler.getConfiguration(), bindingContext, context);
|
||||
project, callableDescriptor, JetChangeSignatureHandler.getConfiguration(), bindingContext, context);
|
||||
}
|
||||
|
||||
private class JavaRefactoringProvider {
|
||||
|
||||
Reference in New Issue
Block a user