Change Signature: Match calls of different overloads generated due to @JvmOverloads annotation
#KT-9020 Fixed
This commit is contained in:
@@ -108,3 +108,8 @@ public fun <T> Collection<T>.toReadOnlyList(): List<T> =
|
||||
|
||||
public fun <T: Any> T?.singletonOrEmptyList(): List<T> =
|
||||
if (this != null) listOf(this) else emptyList()
|
||||
|
||||
public fun <T> MutableList<T>.removeLast(condition: (T) -> Boolean): T? {
|
||||
val index = indexOfLast(condition)
|
||||
return if (index >= 0) removeAt(index) else null
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
@@ -44,11 +45,12 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import java.util.LinkedHashSet
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import org.jetbrains.kotlin.utils.removeLast
|
||||
import java.util.*
|
||||
|
||||
public open class JetChangeInfo(
|
||||
val methodDescriptor: JetMethodDescriptor,
|
||||
@@ -60,7 +62,17 @@ public open class JetChangeInfo(
|
||||
receiver: JetParameterInfo? = methodDescriptor.receiver,
|
||||
val context: PsiElement,
|
||||
primaryPropagationTargets: Collection<PsiElement> = emptyList()
|
||||
): ChangeInfo {
|
||||
) : ChangeInfo {
|
||||
private class JvmOverloadSignature(
|
||||
val method: PsiMethod,
|
||||
val mandatoryParams: Set<KtParameter>,
|
||||
val defaultValues: Set<KtExpression>
|
||||
) {
|
||||
fun constrainBy(other: JvmOverloadSignature): JvmOverloadSignature {
|
||||
return JvmOverloadSignature(method, mandatoryParams.intersect(other.mandatoryParams), defaultValues.intersect(other.defaultValues))
|
||||
}
|
||||
}
|
||||
|
||||
var receiverParameterInfo: JetParameterInfo? = receiver
|
||||
set(value: JetParameterInfo?) {
|
||||
if (value != null && value !in newParameters) {
|
||||
@@ -70,7 +82,10 @@ public open class JetChangeInfo(
|
||||
}
|
||||
|
||||
private val newParameters = parameterInfos.toArrayList()
|
||||
private val originalPsiMethods: List<PsiMethod> = getMethod().toLightMethods()
|
||||
|
||||
private val originalPsiMethods = method.toLightMethods()
|
||||
private val originalParameters = (method as? KtFunction)?.valueParameters ?: emptyList()
|
||||
private val originalSignatures = makeSignatures(originalParameters, originalPsiMethods, { it }, { it.defaultValue })
|
||||
|
||||
private val oldNameToParameterIndex: Map<String, Int> by lazy {
|
||||
val map = HashMap<String, Int>()
|
||||
@@ -90,6 +105,8 @@ public open class JetChangeInfo(
|
||||
|
||||
private var isPrimaryMethodUpdated: Boolean = false
|
||||
private var javaChangeInfos: List<JavaChangeInfo>? = null
|
||||
var originalToCurrentMethods: Map<PsiMethod, PsiMethod> = emptyMap()
|
||||
private set
|
||||
|
||||
public fun getOldParameterIndex(oldParameterName: String): Int? = oldNameToParameterIndex[oldParameterName]
|
||||
|
||||
@@ -114,8 +131,14 @@ public open class JetChangeInfo(
|
||||
newParameters.set(index, parameterInfo)
|
||||
}
|
||||
|
||||
public fun addParameter(parameterInfo: JetParameterInfo) {
|
||||
newParameters.add(parameterInfo)
|
||||
@JvmOverloads
|
||||
public fun addParameter(parameterInfo: JetParameterInfo, atIndex: Int = -1) {
|
||||
if (atIndex >= 0) {
|
||||
newParameters.add(atIndex, parameterInfo)
|
||||
}
|
||||
else {
|
||||
newParameters.add(parameterInfo)
|
||||
}
|
||||
}
|
||||
|
||||
public fun removeParameter(index: Int) {
|
||||
@@ -264,7 +287,56 @@ public open class JetChangeInfo(
|
||||
javaChangeInfos = null
|
||||
}
|
||||
|
||||
private fun <Parameter> makeSignatures(
|
||||
parameters: List<Parameter>,
|
||||
psiMethods: List<PsiMethod>,
|
||||
getPsi: (Parameter) -> KtParameter,
|
||||
getDefaultValue: (Parameter) -> KtExpression?
|
||||
): List<JvmOverloadSignature> {
|
||||
val defaultValueCount = parameters.count { getDefaultValue(it) != null }
|
||||
if (psiMethods.size != defaultValueCount + 1) return emptyList()
|
||||
|
||||
val mandatoryParams = parameters.toArrayList()
|
||||
val defaultValues = ArrayList<KtExpression>()
|
||||
return psiMethods.map {
|
||||
JvmOverloadSignature(it, mandatoryParams.map(getPsi).toSet(), defaultValues.toSet()).apply {
|
||||
val param = mandatoryParams.removeLast { getDefaultValue(it) != null } ?: return@apply
|
||||
defaultValues.add(getDefaultValue(param)!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun getOrCreateJavaChangeInfos(): List<JavaChangeInfo>? {
|
||||
fun initCurrentSignatures(currentPsiMethods: List<PsiMethod>): List<JvmOverloadSignature> {
|
||||
val parameterInfoToPsi = methodDescriptor.original.parameters.zip(originalParameters).toMap()
|
||||
val dummyParameter = KtPsiFactory(method).createParameter("dummy")
|
||||
return makeSignatures(newParameters,
|
||||
currentPsiMethods,
|
||||
{ parameterInfoToPsi[it] ?: dummyParameter },
|
||||
{ it.defaultValueForParameter })
|
||||
}
|
||||
|
||||
fun matchOriginalAndCurrentMethods(currentPsiMethods: List<PsiMethod>): Map<PsiMethod, PsiMethod> {
|
||||
if (!(isPrimaryMethodUpdated
|
||||
&& originalBaseFunctionDescriptor is FunctionDescriptor
|
||||
&& originalBaseFunctionDescriptor.hasJvmOverloadsAnnotation())) {
|
||||
return (originalPsiMethods zip currentPsiMethods).toMap()
|
||||
}
|
||||
|
||||
if (originalPsiMethods.isEmpty() || currentPsiMethods.isEmpty()) return emptyMap()
|
||||
|
||||
currentPsiMethods.singleOrNull()?.let { method -> return originalPsiMethods.keysToMap { method } }
|
||||
|
||||
val currentSignatures = initCurrentSignatures(currentPsiMethods)
|
||||
return originalSignatures.toMap({ it.method }) { originalSignature ->
|
||||
var constrainedCurrentSignatures = currentSignatures.map { it.constrainBy(originalSignature) }
|
||||
val maxMandatoryCount = constrainedCurrentSignatures.maxBy { it.mandatoryParams.size }!!.mandatoryParams.size
|
||||
constrainedCurrentSignatures = constrainedCurrentSignatures.filter { it.mandatoryParams.size == maxMandatoryCount }
|
||||
val maxDefaultCount = constrainedCurrentSignatures.maxBy { it.defaultValues.size }!!.defaultValues.size
|
||||
constrainedCurrentSignatures.last { it.defaultValues.size == maxDefaultCount }.method
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@@ -309,12 +381,27 @@ public open class JetChangeInfo(
|
||||
currentPsiMethod: PsiMethod,
|
||||
newParameterList: List<JetParameterInfo>
|
||||
): MutableList<ParameterInfoImpl> {
|
||||
val defaultValuesToSkip = newParameterList.size - currentPsiMethod.parameterList.parametersCount
|
||||
val defaultValuesToRetain = newParameterList.count { it.defaultValueForParameter != null } - defaultValuesToSkip
|
||||
val oldIndices = newParameterList.map { it.oldIndex }.toIntArray()
|
||||
|
||||
// TODO: Ugly code, need to refactor Change Signature data model
|
||||
var defaultValuesRemained = defaultValuesToRetain
|
||||
for (param in newParameterList) {
|
||||
if (param.isNewParameter || param.defaultValueForParameter == null || defaultValuesRemained-- > 0) continue
|
||||
newParameterList.withIndex().filter { it.value.oldIndex >= param.oldIndex }.forEach { oldIndices[it.index]-- }
|
||||
}
|
||||
|
||||
defaultValuesRemained = defaultValuesToRetain
|
||||
val oldParameterCount = originalPsiMethod.parameterList.parametersCount
|
||||
var indexInCurrentPsiMethod = 0
|
||||
return newParameterList.withIndex()
|
||||
.map { pair ->
|
||||
val (i, info) = pair
|
||||
|
||||
val oldIndex = info.oldIndex
|
||||
if (info.defaultValueForParameter != null && defaultValuesRemained-- <= 0) return@map null
|
||||
|
||||
val oldIndex = oldIndices[i]
|
||||
val javaOldIndex = when {
|
||||
methodDescriptor.receiver == null -> oldIndex
|
||||
info == methodDescriptor.receiver -> 0
|
||||
@@ -324,11 +411,12 @@ public open class JetChangeInfo(
|
||||
if (javaOldIndex >= oldParameterCount) return@map null
|
||||
|
||||
val type = if (isPrimaryMethodUpdated)
|
||||
currentPsiMethod.getParameterList().getParameters()[i].getType()
|
||||
currentPsiMethod.getParameterList().getParameters()[indexInCurrentPsiMethod++].getType()
|
||||
else
|
||||
PsiType.VOID
|
||||
|
||||
ParameterInfoImpl(javaOldIndex, info.getName(), type, info.defaultValueForCall?.getText() ?: "")
|
||||
val defaultValue = info.defaultValueForCall ?: info.defaultValueForParameter
|
||||
ParameterInfoImpl(javaOldIndex, info.getName(), type, defaultValue?.getText() ?: "")
|
||||
}
|
||||
.filterNotNullTo(ArrayList())
|
||||
}
|
||||
@@ -364,7 +452,8 @@ public open class JetChangeInfo(
|
||||
|
||||
if (javaChangeInfos == null) {
|
||||
val method = getMethod()
|
||||
javaChangeInfos = (originalPsiMethods zip method.toLightMethods()).map {
|
||||
originalToCurrentMethods = matchOriginalAndCurrentMethods(method.toLightMethods())
|
||||
javaChangeInfos = originalToCurrentMethods.entries.map {
|
||||
val (originalPsiMethod, currentPsiMethod) = it
|
||||
|
||||
when (method) {
|
||||
@@ -439,11 +528,11 @@ public fun ChangeInfo.toJetChangeInfo(originalChangeSignatureDescriptor: JetMeth
|
||||
val returnTypeText = if (returnType != null) IdeDescriptorRenderers.SOURCE_CODE.renderType(returnType) else ""
|
||||
|
||||
return JetChangeInfo(originalChangeSignatureDescriptor,
|
||||
getNewName(),
|
||||
returnType,
|
||||
returnTypeText,
|
||||
functionDescriptor.getVisibility(),
|
||||
newParameters,
|
||||
null,
|
||||
method)
|
||||
getNewName(),
|
||||
returnType,
|
||||
returnTypeText,
|
||||
functionDescriptor.getVisibility(),
|
||||
newParameters,
|
||||
null,
|
||||
method)
|
||||
}
|
||||
|
||||
+5
-7
@@ -800,14 +800,12 @@ class JetChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
val javaChangeInfos = (changeInfo as JetChangeInfo).getOrCreateJavaChangeInfos()
|
||||
assert(javaChangeInfos != null) { "JavaChangeInfo not found: " + method.text }
|
||||
|
||||
val javaUsageInfos = usageInfo.javaUsageInfos
|
||||
val processors = ChangeSignatureUsageProcessor.EP_NAME.extensions
|
||||
|
||||
for (javaChangeInfo in javaChangeInfos!!) {
|
||||
// Match names so that getter/setter usages are not confused with each other
|
||||
if (javaChangeInfo.oldName != usageInfo.javaChangeInfo.oldName) continue
|
||||
|
||||
javaChangeInfos!!.firstOrNull {
|
||||
changeInfo.originalToCurrentMethods[usageInfo.javaChangeInfo.method] == it.method
|
||||
}?.let { javaChangeInfo ->
|
||||
val nullabilityPropagator = NullabilityPropagator(javaChangeInfo.method)
|
||||
val javaUsageInfos = usageInfo.javaUsageInfos
|
||||
val processors = ChangeSignatureUsageProcessor.EP_NAME.extensions
|
||||
|
||||
for (usage in javaUsageInfos) {
|
||||
if (isOverriderOrCaller(usage) && beforeMethodChange) continue
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
public class JetParameterInfo(
|
||||
public class JetParameterInfo @JvmOverloads constructor (
|
||||
val callableDescriptor: CallableDescriptor,
|
||||
val originalIndex: Int = -1,
|
||||
private var name: String,
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(2, 1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(2, 1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(2, 1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(n: Int = 2, x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 2, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 2, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, n: Int = 2, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0", n: Int = 2) {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo(2);
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(2, 1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(2, 1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(2, 1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(n: Int, x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo(2);
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1, 2);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 2, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 2, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, n: Int, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo(2);
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1, 2);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0, 2);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1", 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0", n: Int) {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
new A();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
new A(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
new A(1, "0", 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
new A(1, "1", 1.0);
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class A @JvmOverloads constructor(
|
||||
public val x: Int = 0,
|
||||
public val z: String = "0",
|
||||
public val y: Double = 0.0
|
||||
)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
new A();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
new A(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
new A(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
new A(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class A @JvmOverloads constructor<caret>(
|
||||
public val x: Int = 0,
|
||||
public val y: Double = 0.0,
|
||||
public val z: String = "0"
|
||||
)
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0) {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooY() {
|
||||
Foo.foo(1.0);
|
||||
}
|
||||
|
||||
void fooYZ() {
|
||||
Foo.foo(1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int, y: Double = 0.0, z: String = "0") {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXZ() {
|
||||
Foo.foo(1, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, z: String = "0") {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo(1.0);
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double, z: String = "0") {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0) {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo("1");
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1, "1");
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(x: Int = 0, y: Double = 0.0, z: String) {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, "0", 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, "1", 1.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun foo(
|
||||
x: Int = 0,
|
||||
z: String = "0",
|
||||
y: Double = 0.0
|
||||
) {
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo();
|
||||
}
|
||||
|
||||
void fooX() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooXY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooXYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(
|
||||
x: Int = 0,
|
||||
y: Double = 0.0,
|
||||
z: String = "0"
|
||||
) {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooY() {
|
||||
Foo.foo("0", 1.0, 1);
|
||||
}
|
||||
|
||||
void fooYZ() {
|
||||
Foo.foo("1", 1.0, 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(
|
||||
z: String = "0",
|
||||
y: Double = 0.0,
|
||||
x: Int
|
||||
) {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class Usages {
|
||||
void foo() {
|
||||
Foo.foo(1);
|
||||
}
|
||||
|
||||
void fooY() {
|
||||
Foo.foo(1, 1.0);
|
||||
}
|
||||
|
||||
void fooYZ() {
|
||||
Foo.foo(1, 1.0, "1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
@file:JvmName("Foo")
|
||||
|
||||
@JvmOverloads
|
||||
fun <caret>foo(
|
||||
x: Int,
|
||||
y: Double = 0.0,
|
||||
z: String = "0"
|
||||
) {
|
||||
|
||||
}
|
||||
+90
@@ -1347,6 +1347,96 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedSwapParams1() throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
JetParameterInfo param = changeInfo.getNewParameters()[1];
|
||||
changeInfo.setNewParameter(1, changeInfo.getNewParameters()[2]);
|
||||
changeInfo.setNewParameter(2, param);
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedSwapParams2() throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
JetParameterInfo param = changeInfo.getNewParameters()[0];
|
||||
changeInfo.setNewParameter(0, changeInfo.getNewParameters()[2]);
|
||||
changeInfo.setNewParameter(2, param);
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
private void doTestJvmOverloadedAddDefault(int index) throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
KtExpression defaultValue = new KtPsiFactory(getProject()).createExpression("2");
|
||||
CallableDescriptor descriptor = changeInfo.getMethodDescriptor().getBaseDescriptor();
|
||||
changeInfo.addParameter(new JetParameterInfo(descriptor, -1, "n", BUILT_INS.getIntType(), defaultValue, defaultValue), index);
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
private void doTestJvmOverloadedAddNonDefault(int index) throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
KtExpression defaultValue = new KtPsiFactory(getProject()).createExpression("2");
|
||||
CallableDescriptor descriptor = changeInfo.getMethodDescriptor().getBaseDescriptor();
|
||||
changeInfo.addParameter(new JetParameterInfo(descriptor, -1, "n", BUILT_INS.getIntType(), null, defaultValue), index);
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
private void doTestRemoveAt(int index) throws Exception {
|
||||
JetChangeInfo changeInfo = getChangeInfo();
|
||||
changeInfo.removeParameter(index >= 0 ? index : changeInfo.getNewParametersCount() - 1);
|
||||
doTest(changeInfo);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedAddDefault1() throws Exception {
|
||||
doTestJvmOverloadedAddDefault(0);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedAddDefault2() throws Exception {
|
||||
doTestJvmOverloadedAddDefault(1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedAddDefault3() throws Exception {
|
||||
doTestJvmOverloadedAddDefault(-1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedAddNonDefault1() throws Exception {
|
||||
doTestJvmOverloadedAddNonDefault(0);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedAddNonDefault2() throws Exception {
|
||||
doTestJvmOverloadedAddNonDefault(1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedAddNonDefault3() throws Exception {
|
||||
doTestJvmOverloadedAddNonDefault(-1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedRemoveDefault1() throws Exception {
|
||||
doTestRemoveAt(0);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedRemoveDefault2() throws Exception {
|
||||
doTestRemoveAt(1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedRemoveDefault3() throws Exception {
|
||||
doTestRemoveAt(-1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedRemoveNonDefault1() throws Exception {
|
||||
doTestRemoveAt(0);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedRemoveNonDefault2() throws Exception {
|
||||
doTestRemoveAt(1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedRemoveNonDefault3() throws Exception {
|
||||
doTestRemoveAt(-1);
|
||||
}
|
||||
|
||||
public void testJvmOverloadedConstructorSwapParams() throws Exception {
|
||||
testJvmOverloadedSwapParams1();
|
||||
}
|
||||
|
||||
private List<Editor> editors = null;
|
||||
|
||||
private static final String[] EXTENSIONS = {".kt", ".java"};
|
||||
|
||||
Reference in New Issue
Block a user