Fix parameters nullability for generated overloads in light classes
When making KtLightNullabilityAnnotation after test org.jetbrains.kotlin.idea.caches.resolve.IdeLightClassTestGenerated.NullabilityAnnotations#testJvmOverloads started failing the wrong assumption was made that for @JvmOverloads-generated overloads their last parameter is always nullable (see removed isNullableInJvmOverloads function) and that lead to a bug, namely KT-28556. The actual problem of this test started failing was incorrect definition of kotlinOrigin in KtLightParameter for case of JvmOverloads: wrong KtParameter was being chosen before This commit fixes the issue by propagating how actually generated parameters in codegen relate to source KtParameters' ^KT-28556 Fixed
This commit is contained in:
+10
-4
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.asJava.builder
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
|
||||
@@ -41,7 +42,7 @@ fun JvmDeclarationOrigin.toLightMemberOrigin(): LightElementOrigin {
|
||||
val originalElement = element
|
||||
return when (originalElement) {
|
||||
is KtAnnotationEntry -> DefaultLightElementOrigin(originalElement)
|
||||
is KtDeclaration -> LightMemberOriginForDeclaration(originalElement, originKind)
|
||||
is KtDeclaration -> LightMemberOriginForDeclaration(originalElement, originKind, parametersForJvmOverload)
|
||||
else -> LightElementOrigin.None
|
||||
}
|
||||
}
|
||||
@@ -49,19 +50,24 @@ fun JvmDeclarationOrigin.toLightMemberOrigin(): LightElementOrigin {
|
||||
interface LightMemberOrigin : LightElementOrigin {
|
||||
override val originalElement: KtDeclaration?
|
||||
override val originKind: JvmDeclarationOriginKind
|
||||
val parametersForJvmOverloads: List<KtParameter?>? get() = null
|
||||
|
||||
fun isEquivalentTo(other: LightMemberOrigin?): Boolean
|
||||
fun copy(): LightMemberOrigin
|
||||
}
|
||||
|
||||
data class LightMemberOriginForDeclaration(override val originalElement: KtDeclaration, override val originKind: JvmDeclarationOriginKind) : LightMemberOrigin {
|
||||
data class LightMemberOriginForDeclaration(
|
||||
override val originalElement: KtDeclaration,
|
||||
override val originKind: JvmDeclarationOriginKind,
|
||||
override val parametersForJvmOverloads: List<KtParameter?>? = null
|
||||
) : LightMemberOrigin {
|
||||
override fun isEquivalentTo(other: LightMemberOrigin?): Boolean {
|
||||
if (other !is LightMemberOriginForDeclaration) return false
|
||||
return originalElement.isEquivalentTo(other.originalElement)
|
||||
}
|
||||
|
||||
override fun copy(): LightMemberOrigin {
|
||||
return LightMemberOriginForDeclaration(originalElement.copy() as KtDeclaration, originKind)
|
||||
return LightMemberOriginForDeclaration(originalElement.copy() as KtDeclaration, originKind, parametersForJvmOverloads)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,4 +77,4 @@ data class DefaultLightElementOrigin(override val originalElement: PsiElement?)
|
||||
|
||||
fun PsiElement?.toLightClassOrigin(): LightElementOrigin {
|
||||
return if (this != null) DefaultLightElementOrigin(this) else LightElementOrigin.None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class KtLightParameter(
|
||||
if (jetIndex < 0) return null
|
||||
|
||||
if (declaration is KtFunction) {
|
||||
val paramList = declaration.valueParameters
|
||||
val paramList = method.lightMemberOrigin?.parametersForJvmOverloads ?: declaration.valueParameters
|
||||
return if (jetIndex < paramList.size) paramList[jetIndex] else null
|
||||
}
|
||||
|
||||
|
||||
+1
-10
@@ -44,7 +44,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -260,7 +259,6 @@ class KtLightNullabilityAnnotation(val member: KtLightElement<*, PsiModifierList
|
||||
|
||||
if (annotatedElement is KtParameter) {
|
||||
if (annotatedElement.containingClassOrObject?.isAnnotation() == true) return null
|
||||
if (isNullableInJvmOverloads(annotatedElement)) return Nullable::class.java.name
|
||||
}
|
||||
|
||||
// don't annotate property setters
|
||||
@@ -289,13 +287,6 @@ class KtLightNullabilityAnnotation(val member: KtLightElement<*, PsiModifierList
|
||||
}
|
||||
}
|
||||
|
||||
private fun isNullableInJvmOverloads(annotatedElement: KtParameter): Boolean {
|
||||
if (annotatedElement.ownerFunction?.let { it.analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, it]?.findJvmOverloadsAnnotation() } == null) return false
|
||||
val lightParameterList = (member as? PsiParameter)?.parent as? PsiParameterList ?: return false
|
||||
val lastParameter = (lightParameterList.parameters.lastOrNull() as? KtLightElement<*, *>)?.kotlinOrigin
|
||||
return lastParameter == annotatedElement
|
||||
}
|
||||
|
||||
internal fun KtTypeReference.getType(): KotlinType? = analyze()[BindingContext.TYPE, this]
|
||||
|
||||
private fun getTargetType(annotatedElement: PsiElement): KotlinType? {
|
||||
@@ -430,4 +421,4 @@ fun <T> withAllowedAnnotationsClsDelegate(body: () -> T): T {
|
||||
} finally {
|
||||
accessAnnotationsClsDelegateIsAllowed = prev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-10
@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -261,7 +260,6 @@ class KtLightNullabilityAnnotation(val member: KtLightElement<*, PsiModifierList
|
||||
|
||||
if (annotatedElement is KtParameter) {
|
||||
if (annotatedElement.containingClassOrObject?.isAnnotation() == true) return null
|
||||
if (isNullableInJvmOverloads(annotatedElement)) return Nullable::class.java.name
|
||||
}
|
||||
|
||||
// don't annotate property setters
|
||||
@@ -290,13 +288,6 @@ class KtLightNullabilityAnnotation(val member: KtLightElement<*, PsiModifierList
|
||||
}
|
||||
}
|
||||
|
||||
private fun isNullableInJvmOverloads(annotatedElement: KtParameter): Boolean {
|
||||
if (annotatedElement.ownerFunction?.let { it.analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, it]?.findJvmOverloadsAnnotation() } == null) return false
|
||||
val lightParameterList = (member as? PsiParameter)?.parent as? PsiParameterList ?: return false
|
||||
val lastParameter = (lightParameterList.parameters.lastOrNull() as? KtLightElement<*, *>)?.kotlinOrigin
|
||||
return lastParameter == annotatedElement
|
||||
}
|
||||
|
||||
internal fun KtTypeReference.getType(): KotlinType? = analyze()[BindingContext.TYPE, this]
|
||||
|
||||
private fun getTargetType(annotatedElement: PsiElement): KotlinType? {
|
||||
@@ -427,4 +418,4 @@ fun <T> withAllowedAnnotationsClsDelegate(body: () -> T): T {
|
||||
} finally {
|
||||
accessAnnotationsClsDelegateIsAllowed = prev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user