mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-31 15:51:59 +00:00
Change Signature: Support implicit calls of 'invoke' and 'get'
Also drop 'operator' keyword when necessary #KT-22718 Fixed
This commit is contained in:
@@ -47,6 +47,8 @@ import org.jetbrains.kotlin.idea.core.compareDescriptors
|
||||
import org.jetbrains.kotlin.idea.refactoring.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.rename.noReceivers
|
||||
import org.jetbrains.kotlin.idea.references.KtArrayAccessReference
|
||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||
@@ -227,24 +229,30 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
val functionPsi = functionUsageInfo.element ?: return
|
||||
|
||||
for (reference in findReferences(functionPsi)) {
|
||||
val element = reference.element
|
||||
val element = reference.element ?: continue
|
||||
|
||||
if (element is KtReferenceExpression) {
|
||||
var parent = element.parent
|
||||
when {
|
||||
reference is KtInvokeFunctionReference || reference is KtArrayAccessReference -> {
|
||||
result.add(KotlinByConventionCallUsage(element as KtExpression, functionUsageInfo))
|
||||
}
|
||||
|
||||
when {
|
||||
parent is KtCallExpression ->
|
||||
result.add(KotlinFunctionCallUsage(parent, functionUsageInfo))
|
||||
element is KtReferenceExpression -> {
|
||||
var parent = element.parent
|
||||
|
||||
parent is KtUserType && parent.parent is KtTypeReference -> {
|
||||
parent = parent.parent.parent
|
||||
when {
|
||||
parent is KtCallExpression ->
|
||||
result.add(KotlinFunctionCallUsage(parent, functionUsageInfo))
|
||||
|
||||
if (parent is KtConstructorCalleeExpression && parent.parent is KtSuperTypeCallEntry)
|
||||
result.add(KotlinFunctionCallUsage(parent.parent as KtSuperTypeCallEntry, functionUsageInfo))
|
||||
parent is KtUserType && parent.parent is KtTypeReference -> {
|
||||
parent = parent.parent.parent
|
||||
|
||||
if (parent is KtConstructorCalleeExpression && parent.parent is KtSuperTypeCallEntry)
|
||||
result.add(KotlinFunctionCallUsage(parent.parent as KtSuperTypeCallEntry, functionUsageInfo))
|
||||
}
|
||||
|
||||
element is KtSimpleNameExpression && (functionPsi is KtProperty || functionPsi is KtParameter) ->
|
||||
result.add(KotlinPropertyCallUsage(element))
|
||||
}
|
||||
|
||||
element is KtSimpleNameExpression && (functionPsi is KtProperty || functionPsi is KtParameter) ->
|
||||
result.add(KotlinPropertyCallUsage(element))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -660,16 +668,20 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
) {
|
||||
if (originalReceiverInfo != null) return
|
||||
|
||||
for (usageInfo in usages) {
|
||||
if (!(usageInfo is KotlinFunctionCallUsage || usageInfo is KotlinPropertyCallUsage)) continue
|
||||
loop@ for (usageInfo in usages) {
|
||||
if (!(usageInfo is KotlinFunctionCallUsage || usageInfo is KotlinPropertyCallUsage || usageInfo is KotlinByConventionCallUsage)) continue
|
||||
|
||||
val callElement = usageInfo.element as? KtElement ?: continue
|
||||
|
||||
val parent = callElement.parent
|
||||
if (parent is KtQualifiedExpression && parent.selectorExpression === callElement) {
|
||||
val message = "Explicit receiver is already present in call element: " + CommonRefactoringUtil.htmlEmphasize(parent.text)
|
||||
result.putValue(callElement, message)
|
||||
|
||||
val elementToReport = when {
|
||||
usageInfo is KotlinByConventionCallUsage -> callElement
|
||||
parent is KtQualifiedExpression && parent.selectorExpression === callElement -> parent
|
||||
else -> continue@loop
|
||||
}
|
||||
|
||||
val message = "Explicit receiver is already present in call element: " + CommonRefactoringUtil.htmlEmphasize(elementToReport.text)
|
||||
result.putValue(callElement, message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -851,6 +863,10 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
}
|
||||
|
||||
if (beforeMethodChange) {
|
||||
if (usageInfo is KotlinUsageInfo<*>) {
|
||||
usageInfo.preprocessUsage()
|
||||
}
|
||||
|
||||
if (method !is PsiMethod || initializedOriginalDescriptor) return false
|
||||
|
||||
val descriptorWrapper = usages.firstIsInstanceOrNull<OriginalJavaMethodDescriptorWrapper>()
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature.usages
|
||||
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.inspections.conventionNameCalls.ReplaceGetOrSetInspection
|
||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.conventionNameCalls.ReplaceInvokeIntention
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeInfo
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPossiblyQualifiedCallExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class KotlinByConventionCallUsage(
|
||||
expression: KtExpression,
|
||||
private val callee: KotlinCallableDefinitionUsage<*>
|
||||
) : KotlinUsageInfo<KtExpression>(expression) {
|
||||
private var resolvedCall: ResolvedCall<*>? = null
|
||||
private var convertedCallExpression: KtCallExpression? = null
|
||||
|
||||
private fun foldExpression(expression: KtDotQualifiedExpression, changeInfo: KotlinChangeInfo) {
|
||||
when (changeInfo.newName) {
|
||||
OperatorNameConventions.INVOKE.asString() -> {
|
||||
with(ReplaceInvokeIntention()) {
|
||||
if (applicabilityRange(expression) != null) {
|
||||
applyTo(expression, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OperatorNameConventions.GET.asString() -> {
|
||||
with(ReplaceGetOrSetInspection()) {
|
||||
if (isApplicable(expression)) {
|
||||
applyTo(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getElement(): KtExpression? {
|
||||
return convertedCallExpression ?: super.getElement()
|
||||
}
|
||||
|
||||
override fun preprocessUsage() {
|
||||
val element = element ?: return
|
||||
val convertedExpression = OperatorToFunctionIntention.convert(element).first
|
||||
val callExpression = convertedExpression.getPossiblyQualifiedCallExpression() ?: return
|
||||
resolvedCall = callExpression.getResolvedCall(callExpression.analyze(BodyResolveMode.PARTIAL))
|
||||
convertedCallExpression = callExpression
|
||||
}
|
||||
|
||||
override fun processUsage(changeInfo: KotlinChangeInfo, element: KtExpression, allUsages: Array<out UsageInfo>): Boolean {
|
||||
val resolvedCall = resolvedCall ?: return true
|
||||
val callExpression = convertedCallExpression ?: return true
|
||||
val callProcessor = KotlinFunctionCallUsage(callExpression, callee, resolvedCall)
|
||||
val newExpression = callProcessor.processUsageAndGetResult(changeInfo, callExpression, allUsages) as? KtExpression
|
||||
val qualifiedCall = newExpression?.getQualifiedExpressionForSelectorOrThis() as? KtDotQualifiedExpression
|
||||
if (qualifiedCall != null) {
|
||||
foldExpression(qualifiedCall, changeInfo)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.idea.refactoring.replaceListPsiAndKeepDelimiters
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences.Options
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.dropOperatorKeywordIfNecessary
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
@@ -140,6 +141,7 @@ class KotlinCallableDefinitionUsage<T : PsiElement>(
|
||||
if (canDropOverride) {
|
||||
dropOverrideKeywordIfNecessary(element)
|
||||
}
|
||||
dropOperatorKeywordIfNecessary(element)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -56,19 +56,28 @@ import java.util.*
|
||||
|
||||
class KotlinFunctionCallUsage(
|
||||
element: KtCallElement,
|
||||
private val callee: KotlinCallableDefinitionUsage<*>
|
||||
private val callee: KotlinCallableDefinitionUsage<*>,
|
||||
forcedResolvedCall: ResolvedCall<*>? = null
|
||||
) : KotlinUsageInfo<KtCallElement>(element) {
|
||||
private val context = element.analyze(BodyResolveMode.FULL)
|
||||
private val resolvedCall = element.getResolvedCall(context)
|
||||
private val resolvedCall = forcedResolvedCall ?: element.getResolvedCall(context)
|
||||
private val skipUnmatchedArgumentsCheck = forcedResolvedCall != null
|
||||
|
||||
override fun processUsage(changeInfo: KotlinChangeInfo, element: KtCallElement, allUsages: Array<out UsageInfo>): Boolean {
|
||||
if (shouldSkipUsage(element)) return true
|
||||
processUsageAndGetResult(changeInfo, element, allUsages)
|
||||
return true
|
||||
}
|
||||
|
||||
fun processUsageAndGetResult(changeInfo: KotlinChangeInfo, element: KtCallElement, allUsages: Array<out UsageInfo>): KtElement {
|
||||
if (shouldSkipUsage(element)) return element
|
||||
|
||||
var result: KtElement = element
|
||||
|
||||
changeNameIfNeeded(changeInfo, element)
|
||||
|
||||
if (element.valueArgumentList != null) {
|
||||
if (changeInfo.isParameterSetOrOrderChanged) {
|
||||
updateArgumentsAndReceiver(changeInfo, element, allUsages)
|
||||
result = updateArgumentsAndReceiver(changeInfo, element, allUsages)
|
||||
}
|
||||
else {
|
||||
changeArgumentNames(changeInfo, element)
|
||||
@@ -83,7 +92,7 @@ class KotlinFunctionCallUsage(
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return result
|
||||
}
|
||||
|
||||
private fun shouldSkipUsage(element: KtCallElement): Boolean {
|
||||
@@ -94,6 +103,8 @@ class KotlinFunctionCallUsage(
|
||||
// TODO: investigate why arguments are not recorded for enum constructor call
|
||||
if (element is KtSuperTypeCallEntry && element.parent.parent is KtEnumEntry) return false
|
||||
|
||||
if (skipUnmatchedArgumentsCheck) return false
|
||||
|
||||
if (!resolvedCall.call.valueArguments.all{ resolvedCall.getArgumentMapping(it) is ArgumentMatch }) return true
|
||||
|
||||
val arguments = resolvedCall.valueArguments
|
||||
@@ -305,7 +316,7 @@ class KotlinFunctionCallUsage(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateArgumentsAndReceiver(changeInfo: KotlinChangeInfo, element: KtCallElement, allUsages: Array<out UsageInfo>) {
|
||||
private fun updateArgumentsAndReceiver(changeInfo: KotlinChangeInfo, element: KtCallElement, allUsages: Array<out UsageInfo>): KtElement {
|
||||
if (isPropertyJavaUsage) return updateJavaPropertyCall(changeInfo, element)
|
||||
|
||||
val fullCallElement = element.getQualifiedExpressionForSelector() ?: element
|
||||
@@ -322,7 +333,7 @@ class KotlinFunctionCallUsage(
|
||||
val dispatchReceiver = resolvedCall?.dispatchReceiver
|
||||
|
||||
// Do not add extension receiver to calls with explicit dispatch receiver
|
||||
if (newReceiverInfo != null && fullCallElement is KtQualifiedExpression && dispatchReceiver is ExpressionReceiver) return
|
||||
if (newReceiverInfo != null && fullCallElement is KtQualifiedExpression && dispatchReceiver is ExpressionReceiver) return element
|
||||
|
||||
val newArgumentInfos = newParameters.withIndex().map {
|
||||
val (index, param) = it
|
||||
@@ -386,7 +397,7 @@ class KotlinFunctionCallUsage(
|
||||
if (it is KtValueArgument) addArgument(it)
|
||||
}
|
||||
|
||||
else -> return
|
||||
else -> return element
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -456,6 +467,8 @@ class KotlinFunctionCallUsage(
|
||||
val newCallExpression = ((newElement as? KtQualifiedExpression)?.selectorExpression ?: newElement) as KtCallExpression
|
||||
newCallExpression.moveFunctionLiteralOutsideParentheses()
|
||||
}
|
||||
|
||||
return newElement
|
||||
}
|
||||
|
||||
private fun changeArgumentNames(changeInfo: KotlinChangeInfo, element: KtCallElement) {
|
||||
@@ -488,10 +501,10 @@ class KotlinFunctionCallUsage(
|
||||
|
||||
private val SHORTEN_ARGUMENTS_OPTIONS = ShortenReferences.Options(true, true)
|
||||
|
||||
private fun updateJavaPropertyCall(changeInfo: KotlinChangeInfo, element: KtCallElement) {
|
||||
private fun updateJavaPropertyCall(changeInfo: KotlinChangeInfo, element: KtCallElement): KtElement {
|
||||
val newReceiverInfo = changeInfo.receiverParameterInfo
|
||||
val originalReceiverInfo = changeInfo.methodDescriptor.receiver
|
||||
if (newReceiverInfo == originalReceiverInfo) return
|
||||
if (newReceiverInfo == originalReceiverInfo) return element
|
||||
|
||||
val arguments = element.valueArgumentList.sure { "Argument list is expected: " + element.text }
|
||||
val oldArguments = element.valueArguments
|
||||
@@ -515,6 +528,8 @@ class KotlinFunctionCallUsage(
|
||||
|
||||
firstArgument != null -> arguments.removeArgument(firstArgument)
|
||||
}
|
||||
|
||||
return element
|
||||
}
|
||||
|
||||
private fun getReceiverExpression(receiver: ReceiverValue, psiFactory: KtPsiFactory): KtExpression? {
|
||||
|
||||
@@ -28,5 +28,7 @@ abstract class KotlinUsageInfo<T : PsiElement> : UsageInfo {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun getElement() = super.getElement() as T?
|
||||
|
||||
open fun preprocessUsage() {}
|
||||
|
||||
abstract fun processUsage(changeInfo: KotlinChangeInfo, element: T, allUsages: Array<out UsageInfo>): Boolean
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
|
||||
import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected
|
||||
import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention
|
||||
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
|
||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.toValVar
|
||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper
|
||||
@@ -85,9 +86,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.AnalyzingUtils
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
@@ -797,6 +796,15 @@ fun dropOverrideKeywordIfNecessary(element: KtNamedDeclaration) {
|
||||
}
|
||||
}
|
||||
|
||||
fun dropOperatorKeywordIfNecessary(element: KtNamedDeclaration) {
|
||||
val callableDescriptor = element.resolveToDescriptorIfAny() as? CallableDescriptor ?: return
|
||||
val diagnosticHolder = BindingTraceContext()
|
||||
OperatorModifierChecker.check(element, callableDescriptor, diagnosticHolder, element.languageVersionSettings)
|
||||
if (diagnosticHolder.bindingContext.diagnostics.any { it.factory == Errors.INAPPLICABLE_OPERATOR_MODIFIER }) {
|
||||
element.removeModifier(KtTokens.OPERATOR_KEYWORD)
|
||||
}
|
||||
}
|
||||
|
||||
fun getQualifiedTypeArgumentList(
|
||||
initializer: KtExpression,
|
||||
context: BindingContext = initializer.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionAddParameterAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionAddParameterAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun get(s: String, i: Int, b: Boolean) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42, false]
|
||||
A()["", 42, false]
|
||||
a.get("", 42, false)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionAddParameterBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionAddParameterBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>get(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionParameterToReceiverBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionParameterToReceiverBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>get(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
3
idea/testData/refactoring/changeSignature/GetConventionParameterToReceiverMessages.txt
vendored
Normal file
3
idea/testData/refactoring/changeSignature/GetConventionParameterToReceiverMessages.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Explicit receiver is already present in call element: A()["", 42]
|
||||
Explicit receiver is already present in call element: a.get("", 42)
|
||||
Explicit receiver is already present in call element: a["", 42]
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionReceiverToParameterAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionReceiverToParameterAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun get(a: A, s: String, i: Int) {}
|
||||
|
||||
fun usage(a: A) {
|
||||
get(a, "", 42)
|
||||
get(A(), "", 42)
|
||||
get(a, "", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionReceiverToParameterBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionReceiverToParameterBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
operator fun A.<caret>get(s: String, i: Int) {}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionRemoveParameterAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionRemoveParameterAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun get(i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a[42]
|
||||
A()[42]
|
||||
a.get(42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionRemoveParameterBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionRemoveParameterBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>get(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionRenameToFooAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionRenameToFooAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
fun foo(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a.foo("", 42)
|
||||
A().foo("", 42)
|
||||
a.foo("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionRenameToFooBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionRenameToFooBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>get(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionRenameToInvokeAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionRenameToInvokeAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun invoke(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionRenameToInvokeBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionRenameToInvokeBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>get(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionSwapParametersAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionSwapParametersAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun get(i: Int, s: String) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a[42, ""]
|
||||
A()[42, ""]
|
||||
a.get(42, "")
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/GetConventionSwapParametersBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/GetConventionSwapParametersBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>get(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionAddParameterAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionAddParameterAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun invoke(s: String, i: Int, b: Boolean) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42, false)
|
||||
A()("", 42, false)
|
||||
a.invoke("", 42, false)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionAddParameterBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionAddParameterBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>invoke(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionParameterToReceiverBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionParameterToReceiverBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>invoke(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
3
idea/testData/refactoring/changeSignature/InvokeConventionParameterToReceiverMessages.txt
vendored
Normal file
3
idea/testData/refactoring/changeSignature/InvokeConventionParameterToReceiverMessages.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Explicit receiver is already present in call element: A()("", 42)
|
||||
Explicit receiver is already present in call element: a("", 42)
|
||||
Explicit receiver is already present in call element: a.invoke("", 42)
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionReceiverToParameterAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionReceiverToParameterAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
fun invoke(a: A, s: String, i: Int) {}
|
||||
|
||||
fun usage(a: A) {
|
||||
invoke(a, "", 42)
|
||||
invoke(A(), "", 42)
|
||||
invoke(a, "", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionReceiverToParameterBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionReceiverToParameterBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A
|
||||
|
||||
operator fun A.<caret>invoke(s: String, i: Int) {}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionRemoveParameterAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionRemoveParameterAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun invoke(i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a(42)
|
||||
A()(42)
|
||||
a.invoke(42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionRemoveParameterBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionRemoveParameterBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>invoke(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToFooAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToFooAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
fun foo(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a.foo("", 42)
|
||||
A().foo("", 42)
|
||||
a.foo("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToFooBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToFooBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>invoke(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToGetAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToGetAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun get(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a["", 42]
|
||||
A()["", 42]
|
||||
a.get("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToGetBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionRenameToGetBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>invoke(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionSwapParametersAfter.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionSwapParametersAfter.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun invoke(i: Int, s: String) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a(42, "")
|
||||
A()(42, "")
|
||||
a.invoke(42, "")
|
||||
}
|
||||
9
idea/testData/refactoring/changeSignature/InvokeConventionSwapParametersBefore.kt
vendored
Normal file
9
idea/testData/refactoring/changeSignature/InvokeConventionSwapParametersBefore.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun <caret>invoke(s: String, i: Int) {}
|
||||
}
|
||||
|
||||
fun usage(a: A) {
|
||||
a("", 42)
|
||||
A()("", 42)
|
||||
a.invoke("", 42)
|
||||
}
|
||||
@@ -960,4 +960,52 @@ class KotlinChangeSignatureTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
fun testChangeReturnTypeToNonUnit() = doTest {
|
||||
newReturnTypeInfo = KotlinTypeInfo(true, BUILT_INS.intType)
|
||||
}
|
||||
|
||||
fun testInvokeConventionRemoveParameter() = doTest { removeParameter(0) }
|
||||
|
||||
fun testInvokeConventionAddParameter() = doTest {
|
||||
addParameter(
|
||||
KotlinParameterInfo(
|
||||
originalBaseFunctionDescriptor,
|
||||
-1,
|
||||
"b",
|
||||
KotlinTypeInfo(false, BUILT_INS.booleanType),
|
||||
defaultValueForCall = KtPsiFactory(project).createExpression("false")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testInvokeConventionSwapParameters() = doTest { swapParameters(0, 1) }
|
||||
|
||||
fun testInvokeConventionParameterToReceiver() = doTestConflict { receiverParameterInfo = newParameters[0] }
|
||||
|
||||
fun testInvokeConventionReceiverToParameter() = doTest { receiverParameterInfo = null }
|
||||
|
||||
fun testInvokeConventionRenameToFoo() = doTest { newName = "foo" }
|
||||
|
||||
fun testInvokeConventionRenameToGet() = doTest { newName = "get" }
|
||||
|
||||
fun testGetConventionRemoveParameter() = doTest { removeParameter(0) }
|
||||
|
||||
fun testGetConventionAddParameter() = doTest {
|
||||
addParameter(
|
||||
KotlinParameterInfo(
|
||||
originalBaseFunctionDescriptor,
|
||||
-1,
|
||||
"b",
|
||||
KotlinTypeInfo(false, BUILT_INS.booleanType),
|
||||
defaultValueForCall = KtPsiFactory(project).createExpression("false")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun testGetConventionSwapParameters() = doTest { swapParameters(0, 1) }
|
||||
|
||||
fun testGetConventionParameterToReceiver() = doTestConflict { receiverParameterInfo = newParameters[0] }
|
||||
|
||||
fun testGetConventionReceiverToParameter() = doTest { receiverParameterInfo = null }
|
||||
|
||||
fun testGetConventionRenameToFoo() = doTest { newName = "foo" }
|
||||
|
||||
fun testGetConventionRenameToInvoke() = doTest { newName = "invoke" }
|
||||
}
|
||||
Reference in New Issue
Block a user