[change signature] improve rendering of flexible parameters

^KTIJ-707 Fixed

GitOrigin-RevId: 6a555b8842c9f5deff140a3fe16a41c91a94d6a9
This commit is contained in:
Dmitry Gridin
2021-01-25 09:35:03 +03:00
committed by intellij-monorepo-bot
parent e4a3aa92ba
commit 82d94745a5
30 changed files with 313 additions and 10 deletions
@@ -28,10 +28,11 @@ import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.types.FlexibleType
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class KotlinParameterInfo(
val callableDescriptor: CallableDescriptor,
@@ -86,12 +87,11 @@ class KotlinParameterInfo(
if (parameter.isVararg) return defaultRendering
val parameterType = parameter.type
if (parameterType.isError) return defaultRendering
val typeToRender = parameterType.safeAs<FlexibleType>()?.let { flexibleType ->
val originalType = inheritedCallable.originalCallableDescriptor.valueParameters.getOrNull(originalIndex)?.type
if (originalType?.isSubtypeOf(flexibleType.upperBound) == true && flexibleType.lowerBound.isSubtypeOf(originalType))
originalType
else
null
val originalType = inheritedCallable.originalCallableDescriptor.valueParameters.getOrNull(originalIndex)?.type
val typeToRender = originalType?.takeIf {
val checker = OverridingTypeCheckerContext.createChecker(inheritedCallable.originalCallableDescriptor, currentBaseFunction)
AbstractTypeChecker.equalTypes(checker as AbstractTypeCheckerContext, originalType.unwrap(), parameterType.unwrap())
} ?: parameterType
return typeToRender.renderTypeWithSubstitution(typeSubstitutor, defaultRendering, true)
@@ -259,3 +259,20 @@ private fun defaultValOrVar(callableDescriptor: CallableDescriptor): KotlinValVa
KotlinValVar.Val
else
KotlinValVar.None
private class OverridingTypeCheckerContext(private val matchingTypeConstructors: Map<TypeConstructor, TypeConstructor>) :
ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) {
override fun areEqualTypeConstructors(a: TypeConstructor, b: TypeConstructor): Boolean = super.areEqualTypeConstructors(a, b) || run {
val img1 = matchingTypeConstructors[a]
val img2 = matchingTypeConstructors[b]
img1 != null && img1 == b || img2 != null && img2 == a
}
companion object {
fun createChecker(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor): OverridingTypeCheckerContext {
return OverridingTypeCheckerContext(subDescriptor.typeParameters.zip(superDescriptor.typeParameters).associate {
it.first.typeConstructor to it.second.typeConstructor
})
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -591,6 +591,34 @@ class KotlinChangeSignatureTest : KotlinLightCodeInsightFixtureTestCase() {
}
}
fun testChangeJavaMethod() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "i", PsiType.INT)) }
}
fun testChangeJavaMethodWithPrimitiveType() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType)) }
}
fun testChangeJavaMethodWithBoxedType() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType)) }
}
fun testChangeJavaMethodWithFlexibleMutableType() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType)) }
}
fun testChangeJavaMethodWithNestedFlexibleType() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "i", PsiType.INT)) }
}
fun testChangeJavaMethodWithFlexibleMutableType1() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "s", stringPsiType)) }
}
fun testChangeJavaMethodWithRawType() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "i", PsiType.INT)) }
}
fun testSimpleFlexibleType() {
doJavaTest { newParameters.add(ParameterInfoImpl(-1, "integer", PsiType.INT)) }
}
@@ -0,0 +1,3 @@
class KOne : MyJavaClass() {
override fun meth(s: String, i: Int) = Unit
}
@@ -0,0 +1,3 @@
abstract public class MyJavaClass {
public abstract void meth(String s, int i);
}
@@ -0,0 +1,3 @@
class KOne : MyJavaClass() {
override fun meth(s: String) = Unit
}
@@ -0,0 +1,3 @@
abstract public class MyJavaClass {
public abstract void me<caret>th(String s);
}
@@ -0,0 +1,7 @@
class KOne : MyJavaClass() {
override fun meth(i: Int, s: String) = Unit
}
class KTwo : MyJavaClass() {
override fun meth(i: Int?, s: String) = Unit
}
@@ -0,0 +1,3 @@
abstract public class MyJavaClass {
public abstract void me<caret>th(Integer i, String s);
}
@@ -0,0 +1,7 @@
class KOne : MyJavaClass() {
override fun meth(i: Int) = Unit
}
class KTwo : MyJavaClass() {
override fun meth(i: Int?) = Unit
}
@@ -0,0 +1,3 @@
abstract public class MyJavaClass {
public abstract void me<caret>th(Integer i);
}
@@ -0,0 +1,31 @@
class K1 : MyJavaClass() {
override fun meth(c: Collection<Int>?, s: String) = Unit
}
class K2 : MyJavaClass() {
override fun meth(c: Collection<Int>, s: String) = Unit
}
class K3 : MyJavaClass() {
override fun meth(c: MutableCollection<Int>?, s: String) = Unit
}
class K4 : MyJavaClass() {
override fun meth(c: MutableCollection<Int>, s: String) = Unit
}
class K5 : MyJavaClass() {
override fun meth(c: Collection<Int?>?, s: String) = Unit
}
class K6 : MyJavaClass() {
override fun meth(c: Collection<Int?>, s: String) = Unit
}
class K7 : MyJavaClass() {
override fun meth(c: MutableCollection<Int?>?, s: String) = Unit
}
class K8 : MyJavaClass() {
override fun meth(c: MutableCollection<Int?>, s: String) = Unit
}
@@ -0,0 +1,5 @@
import java.util.Collection;
abstract public class MyJavaClass {
public abstract void me<caret>th(Collection<Integer> c, String s);
}
@@ -0,0 +1,31 @@
class K1 : MyJavaClass() {
override fun meth(c: Collection<Int>?) = Unit
}
class K2 : MyJavaClass() {
override fun meth(c: Collection<Int>) = Unit
}
class K3 : MyJavaClass() {
override fun meth(c: MutableCollection<Int>?) = Unit
}
class K4 : MyJavaClass() {
override fun meth(c: MutableCollection<Int>) = Unit
}
class K5 : MyJavaClass() {
override fun meth(c: Collection<Int?>?) = Unit
}
class K6 : MyJavaClass() {
override fun meth(c: Collection<Int?>) = Unit
}
class K7 : MyJavaClass() {
override fun meth(c: MutableCollection<Int?>?) = Unit
}
class K8 : MyJavaClass() {
override fun meth(c: MutableCollection<Int?>) = Unit
}
@@ -0,0 +1,5 @@
import java.util.Collection;
abstract public class MyJavaClass {
public abstract void me<caret>th(Collection<Integer> c);
}
@@ -0,0 +1,31 @@
class K1 : MyJavaClass() {
override fun <T> meth(c: Collection<T>?, s: String) = Unit
}
class K2 : MyJavaClass() {
override fun <T> meth(c: Collection<T>, s: String) = Unit
}
class K3 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T>?, s: String) = Unit
}
class K4 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T>, s: String) = Unit
}
class K5 : MyJavaClass() {
override fun <T> meth(c: Collection<T?>?, s: String) = Unit
}
class K6 : MyJavaClass() {
override fun <T> meth(c: Collection<T?>, s: String) = Unit
}
class K7 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T?>?, s: String) = Unit
}
class K8 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T?>, s: String) = Unit
}
@@ -0,0 +1,5 @@
import java.util.Collection;
abstract public class MyJavaClass {
public abstract <T> void meth(Collection<T> c, String s);
}
@@ -0,0 +1,31 @@
class K1 : MyJavaClass() {
override fun <T> meth(c: Collection<T>?) = Unit
}
class K2 : MyJavaClass() {
override fun <T> meth(c: Collection<T>) = Unit
}
class K3 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T>?) = Unit
}
class K4 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T>) = Unit
}
class K5 : MyJavaClass() {
override fun <T> meth(c: Collection<T?>?) = Unit
}
class K6 : MyJavaClass() {
override fun <T> meth(c: Collection<T?>) = Unit
}
class K7 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T?>?) = Unit
}
class K8 : MyJavaClass() {
override fun <T> meth(c: MutableCollection<T?>) = Unit
}
@@ -0,0 +1,5 @@
import java.util.Collection;
abstract public class MyJavaClass {
public abstract <T> void met<caret>h(Collection<T> c);
}
@@ -0,0 +1,7 @@
class K1 : MyJavaCLass() {
override fun coll(c: Collection<Int?>, i: Int) = Unit
}
class K2 : MyJavaCLass() {
override fun coll(c: Collection<Int>, i: Int) = Unit
}
@@ -0,0 +1,8 @@
import kotlin.annotations.jvm.ReadOnly;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
abstract public class MyJavaCLass {
public abstract void col<caret>l(@ReadOnly @NotNull Collection<Integer> c, int i);
}
@@ -0,0 +1,7 @@
class K1 : MyJavaCLass() {
override fun coll(c: Collection<Int?>) = Unit
}
class K2 : MyJavaCLass() {
override fun coll(c: Collection<Int>) = Unit
}
@@ -0,0 +1,8 @@
import kotlin.annotations.jvm.ReadOnly;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
abstract public class MyJavaCLass {
public abstract void col<caret>l(@ReadOnly @NotNull Collection<Integer> c);
}
@@ -0,0 +1,3 @@
class KOne : MyJavaClass() {
override fun meth(i: Int, s: String) = Unit
}
@@ -0,0 +1,3 @@
abstract public class MyJavaClass {
public abstract void meth(int i, String s);
}
@@ -0,0 +1,3 @@
class KOne : MyJavaClass() {
override fun meth(i: Int) = Unit
}
@@ -0,0 +1,3 @@
abstract public class MyJavaClass {
public abstract void me<caret>th(int i);
}
@@ -0,0 +1,15 @@
class K1 : MyJavaClass() {
override fun coll(c: Collection<Any?>?, i: Int) = Unit
}
class K2 : MyJavaClass() {
override fun coll(c: Collection<Any?>, i: Int) = Unit
}
class K3 : MyJavaClass() {
override fun coll(c: MutableCollection<Any?>, i: Int) = Unit
}
class K4 : MyJavaClass() {
override fun coll(c: MutableCollection<Any?>?, i: Int) = Unit
}
@@ -0,0 +1,5 @@
import java.util.Collection;
abstract public class MyJavaClass {
public abstract void co<caret>ll(Collection c, int i);
}
@@ -0,0 +1,15 @@
class K1 : MyJavaClass() {
override fun coll(c: Collection<Any?>?) = Unit
}
class K2 : MyJavaClass() {
override fun coll(c: Collection<Any?>) = Unit
}
class K3 : MyJavaClass() {
override fun coll(c: MutableCollection<Any?>) = Unit
}
class K4 : MyJavaClass() {
override fun coll(c: MutableCollection<Any?>?) = Unit
}
@@ -0,0 +1,5 @@
import java.util.Collection;
abstract public class MyJavaClass {
public abstract void co<caret>ll(Collection c);
}