Kapt: typeElement.asType() should preserve type parameters and propagate it to its supertypes (KT-13865)
(cherry picked from commit 92c9cea)
This commit is contained in:
committed by
Yan Zhulanow
parent
a22721fbd8
commit
f83e7509b2
+3
-2
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.java.model.elements.JeAnnotationMirror
|
||||
import org.jetbrains.kotlin.java.model.elements.JeMethodExecutableElement
|
||||
import org.jetbrains.kotlin.java.model.elements.JePackageElement
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import java.io.PrintWriter
|
||||
import java.io.Writer
|
||||
import javax.lang.model.element.*
|
||||
@@ -48,7 +49,7 @@ class KotlinElements(
|
||||
val hiderMethodClass = hiderMethod.containingClass ?: return false
|
||||
val hiddenMethodClass = hiddenMethod.containingClass ?: return false
|
||||
|
||||
if (PsiTypesUtil.getClassType(hiddenMethodClass) !in hiderMethodClass.superTypes) return false
|
||||
if (hiddenMethodClass.getTypeWithTypeParameters() !in hiderMethodClass.superTypes) return false
|
||||
|
||||
return isSubSignature(hiderMethod, hiddenMethod)
|
||||
}
|
||||
@@ -148,7 +149,7 @@ class KotlinElements(
|
||||
|
||||
private fun PsiClass.isSubclassOf(other: PsiClass?): Boolean {
|
||||
if (other == null) return false
|
||||
return TypeConversionUtil.isAssignable(PsiTypesUtil.getClassType(other), PsiTypesUtil.getClassType(this), false)
|
||||
return TypeConversionUtil.isAssignable(other.getTypeWithTypeParameters(), this.getTypeWithTypeParameters(), false)
|
||||
}
|
||||
|
||||
private fun isSubSignature(childMethod: PsiMethod, superMethod: PsiMethod): Boolean {
|
||||
|
||||
+2
-7
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.annotation.processing.impl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.*
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
@@ -135,10 +134,6 @@ class KotlinTypes(
|
||||
override fun directSupertypes(t: TypeMirror): List<TypeMirror> {
|
||||
if (t is NoType || t is ExecutableType) throw IllegalArgumentException("Invalid type: $t")
|
||||
|
||||
if (t is JeDeclaredType && t.psiType is PsiImmediateClassType) {
|
||||
return t.psiClass.superTypes.map { it.toJeType(psiManager()) }
|
||||
}
|
||||
|
||||
val psiType = (t as? JePsiType)?.psiType as? PsiClassType ?: return emptyList()
|
||||
return psiType.superTypes.map { it.toJeType(psiManager()) }
|
||||
}
|
||||
@@ -197,7 +192,7 @@ class KotlinTypes(
|
||||
i, t -> (t as? JePsiType)?.psiType ?: throw IllegalArgumentException("Invalid type argument #$i: $t")
|
||||
}
|
||||
|
||||
val psiType = createDeclaredType(psiClass, typeArgs) ?:
|
||||
val psiType = createImmediateClassType(psiClass, typeArgs) ?:
|
||||
throw IllegalStateException("Can't create declared type ($psiClass, $typeArgs)")
|
||||
return JeDeclaredType(psiType, psiClass)
|
||||
}
|
||||
@@ -229,7 +224,7 @@ class KotlinTypes(
|
||||
i, t -> (t as? JePsiType)?.psiType ?: throw IllegalArgumentException("Invalid type argument #$i: $t")
|
||||
}
|
||||
|
||||
val psiType = createDeclaredType(psiClass, typeArgs) ?:
|
||||
val psiType = createImmediateClassType(psiClass, typeArgs) ?:
|
||||
throw IllegalStateException("Can't create declared type ($psiClass, $typeArgs)")
|
||||
return JeDeclaredType(psiType, psiClass, containing)
|
||||
}
|
||||
|
||||
@@ -11,4 +11,7 @@ class C<T : CharSequence> : A<T>()
|
||||
|
||||
interface I2<X>
|
||||
open class B2<X>
|
||||
class A2<T : CharSequence> : B2<T>(), I2<T>
|
||||
class A2<T : CharSequence> : B2<T>(), I2<T>
|
||||
|
||||
interface I3<T>
|
||||
class A3<T> : I3<List<T>>
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.types.JeDeclaredErrorType
|
||||
import org.jetbrains.kotlin.java.model.types.JeDeclaredType
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
@@ -28,7 +28,7 @@ import javax.lang.model.type.DeclaredType
|
||||
class JeAnnotationMirror(val psi: PsiAnnotation) : AnnotationMirror {
|
||||
override fun getAnnotationType(): DeclaredType? {
|
||||
val psiClass = resolveAnnotationClass() ?: return JeDeclaredErrorType
|
||||
return JeDeclaredType(PsiTypesUtil.getClassType(psiClass), psiClass)
|
||||
return JeDeclaredType(psiClass.getTypeWithTypeParameters(), psiClass)
|
||||
}
|
||||
|
||||
override fun getElementValues(): Map<out ExecutableElement, AnnotationValue> = getElementValues(false)
|
||||
|
||||
+4
-4
@@ -17,8 +17,8 @@
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.internal.isStatic
|
||||
import org.jetbrains.kotlin.java.model.types.JeMethodExecutableTypeMirror
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
@@ -84,7 +84,7 @@ fun PsiMethod.getReceiverTypeMirror(): TypeMirror {
|
||||
val containingClass = containingClass
|
||||
if (containingClass != null && !containingClass.isStatic) {
|
||||
containingClass.containingClass?.let {
|
||||
return PsiTypesUtil.getClassType(it).toJeType(manager)
|
||||
return it.getTypeWithTypeParameters().toJeType(manager)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,6 @@ fun PsiMethod.getReceiverTypeMirror(): TypeMirror {
|
||||
}
|
||||
|
||||
val containingClass = containingClass ?: return JeNoneType
|
||||
return PsiTypesUtil.getClassType(containingClass).toJeType(manager)
|
||||
|
||||
return containingClass.getTypeWithTypeParameters().toJeType(manager)
|
||||
|
||||
}
|
||||
+4
-4
@@ -19,10 +19,10 @@ package org.jetbrains.kotlin.java.model.elements
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType
|
||||
import com.intellij.psi.util.ClassUtil
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.asJava.elements.LightParameter
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.DefaultConstructorPsiMethod
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.*
|
||||
@@ -41,7 +41,7 @@ class JeTypeElement(override val psi: PsiClass) : JeElement, TypeElement, JeAnno
|
||||
|
||||
private fun getSuperType(superTypes: Array<PsiClassType>, superClass: PsiClass): PsiClassType {
|
||||
return superTypes.firstOrNull { it is PsiClassReferenceType && it.resolve() == superClass }
|
||||
?: PsiTypesUtil.getClassType(superClass)
|
||||
?: superClass.getTypeWithTypeParameters()
|
||||
}
|
||||
|
||||
override fun getSuperclass(): TypeMirror {
|
||||
@@ -94,7 +94,7 @@ class JeTypeElement(override val psi: PsiClass) : JeElement, TypeElement, JeAnno
|
||||
declarations += JeMethodExecutableElement(DefaultConstructorPsiMethod(psi, psi.language).apply {
|
||||
val containingClass = psi.containingClass
|
||||
if (containingClass != null && !psi.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
addParameter(LightParameter("\$instance", PsiTypesUtil.getClassType(containingClass), this, psi.language))
|
||||
addParameter(LightParameter("\$instance", containingClass.getTypeWithTypeParameters(), this, psi.language))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -125,7 +125,7 @@ class JeTypeElement(override val psi: PsiClass) : JeElement, TypeElement, JeAnno
|
||||
else -> ElementKind.CLASS
|
||||
}
|
||||
|
||||
override fun asType() = PsiTypesUtil.getClassType(psi).toJeType(psi.manager)
|
||||
override fun asType() = psi.getTypeWithTypeParameters().toJeType(psi.manager)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitType(this, p)
|
||||
|
||||
|
||||
+3
-8
@@ -16,14 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import com.intellij.psi.PsiTypeParameter
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.JeAnnotationOwner
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
import org.jetbrains.kotlin.java.model.JeModifierListOwner
|
||||
import org.jetbrains.kotlin.java.model.JeName
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
@@ -40,7 +35,7 @@ class JeTypeParameterElement(
|
||||
|
||||
override fun getKind() = ElementKind.TYPE_PARAMETER
|
||||
|
||||
override fun asType() = PsiTypesUtil.getClassType(psi).toJeType(psi.manager)
|
||||
override fun asType() = psi.getTypeWithTypeParameters().toJeType(psi.manager)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitTypeParameter(this, p)
|
||||
|
||||
|
||||
+9
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.java.model.internal
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.PsiModifier.*
|
||||
import com.intellij.psi.impl.PsiSubstitutorImpl
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightAnnotation
|
||||
import javax.lang.model.element.Modifier
|
||||
|
||||
@@ -91,6 +93,13 @@ fun PsiModifierListOwner.getAnnotationsWithInherited(): List<PsiAnnotation> {
|
||||
return annotations
|
||||
}
|
||||
|
||||
fun PsiClass.getTypeWithTypeParameters(): PsiClassType {
|
||||
val elementFactory = JavaPsiFacade.getElementFactory(project)
|
||||
val params = mutableMapOf<PsiTypeParameter, PsiType>()
|
||||
typeParameters.forEach { params.put(it, PsiTypesUtil.getClassType(it)) }
|
||||
return elementFactory.createType(this, PsiSubstitutorImpl.createSubstitutor(params))
|
||||
}
|
||||
|
||||
private fun PsiAnnotation.isInherited(): Boolean {
|
||||
val annotationClass = nameReferenceElement?.resolve() as? PsiClass ?: return false
|
||||
val annotations = annotationClass.modifierList?.annotations ?: return false
|
||||
|
||||
+12
-10
@@ -18,22 +18,24 @@ package org.jetbrains.kotlin.java.model.types
|
||||
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.light.LightClassReferenceExpression
|
||||
import com.intellij.psi.impl.PsiSubstitutorImpl
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
||||
import org.jetbrains.kotlin.java.model.internal.getTypeWithTypeParameters
|
||||
import org.jetbrains.kotlin.java.model.internal.isStatic
|
||||
import javax.lang.model.type.DeclaredType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
fun createDeclaredType(psiClass: PsiClass, typeArgs: List<PsiType>): PsiClassReferenceType? {
|
||||
val args = typeArgs.toTypedArray()
|
||||
val text = (psiClass.name ?: return null) + typeArgs.joinToString(prefix = "<", postfix = ">") { it.canonicalText }
|
||||
return PsiClassReferenceType(object : LightClassReferenceExpression(psiClass.manager, text, psiClass) {
|
||||
override fun getTypeParameters() = args
|
||||
}, LanguageLevel.JDK_1_8)
|
||||
fun createImmediateClassType(psiClass: PsiClass, typeArgs: List<PsiType>): PsiImmediateClassType? {
|
||||
val typeParameters = psiClass.typeParameters
|
||||
assert(typeParameters.size == typeArgs.size) { "Type parameters size: ${typeParameters.size}, type args size: ${typeArgs.size}" }
|
||||
|
||||
val parametersMap = typeParameters.zip(typeArgs).toMap()
|
||||
val substitutor = PsiSubstitutorImpl.createSubstitutor(parametersMap)
|
||||
return PsiImmediateClassType(psiClass, substitutor, LanguageLevel.JDK_1_8)
|
||||
}
|
||||
|
||||
class JeDeclaredType(
|
||||
@@ -64,7 +66,7 @@ class JeDeclaredType(
|
||||
if (substitutedParameter != null)
|
||||
args += substitutedParameter.toJeType(psiManager)
|
||||
else
|
||||
args += JeTypeVariableType(PsiTypesUtil.getClassType(typeParameter), typeParameter)
|
||||
args += JeTypeVariableType(typeParameter.getTypeWithTypeParameters(), typeParameter)
|
||||
}
|
||||
|
||||
args
|
||||
@@ -81,7 +83,7 @@ class JeDeclaredType(
|
||||
if (enclosingDeclaredType != null) return enclosingDeclaredType
|
||||
|
||||
val psiClass = psiClass.containingClass ?: return JeNoneType
|
||||
return PsiTypesUtil.getClassType(psiClass).toJeType(psiManager)
|
||||
return psiClass.getTypeWithTypeParameters().toJeType(psiManager)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
||||
+11
-2
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.annotation.processing.test.processor
|
||||
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.impl.PsiSubstitutorImpl
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.kotlin.annotation.processing.impl.DisposableRef
|
||||
import org.jetbrains.kotlin.annotation.processing.impl.KotlinProcessingEnvironment
|
||||
@@ -148,11 +151,11 @@ class ProcessorTests : AbstractProcessorTest() {
|
||||
assertEquals(2, bASuperTypes.size) // Object and I
|
||||
|
||||
fun List<TypeMirror>.iInterface() = first { it.toString().matches("I(<.*>)?".toRegex()) } as DeclaredType
|
||||
|
||||
|
||||
val bai = bASuperTypes.iInterface()
|
||||
assertEquals(1, bai.typeArguments.size)
|
||||
assertEquals("java.lang.String", bai.typeArguments.first().toString())
|
||||
|
||||
|
||||
val c = env.findClass("C")
|
||||
val cSuperTypes = env.typeUtils.directSupertypes(c.asType())
|
||||
assertEquals(1, cSuperTypes.size)
|
||||
@@ -164,6 +167,12 @@ class ProcessorTests : AbstractProcessorTest() {
|
||||
val a2 = env.findClass("A2")
|
||||
val i2 = env.typeUtils.directSupertypes(a2.asType()).first { it.toString().matches("I2(<.*>)?".toRegex()) } as JeDeclaredType
|
||||
assertEquals("I2<T>", i2.toString())
|
||||
|
||||
val stringType = env.elementUtils.getTypeElement("java.lang.String").asType()
|
||||
val a3 = env.findClass("A3")
|
||||
val resolvedA3 = env.typeUtils.getDeclaredType(a3, stringType)
|
||||
val i3 = env.typeUtils.directSupertypes(resolvedA3).first { it.toString().matches("I3(<.*>)?".toRegex()) } as JeDeclaredType
|
||||
assertEquals("I3<java.util.List<? extends java.lang.String>>", i3.toString())
|
||||
}
|
||||
|
||||
fun testErasureSimple() = test("ErasureSimple", "*") { set, roundEnv, env ->
|
||||
|
||||
Reference in New Issue
Block a user