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:
Yan Zhulanow
2016-09-21 23:26:58 +03:00
committed by Yan Zhulanow
parent a22721fbd8
commit f83e7509b2
10 changed files with 54 additions and 40 deletions
@@ -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)
@@ -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)
}
@@ -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)
@@ -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)
@@ -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
@@ -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 {