diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt index 2b6f46f7d15..f00b43afc52 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinElements.kt @@ -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 { diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt index f3b7829e353..ce93ad0be44 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinTypes.kt @@ -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 { 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) } diff --git a/plugins/annotation-processing/testData/processors/TypeArguments2.kt b/plugins/annotation-processing/testData/processors/TypeArguments2.kt index cf04e58650d..26b5d64c46d 100644 --- a/plugins/annotation-processing/testData/processors/TypeArguments2.kt +++ b/plugins/annotation-processing/testData/processors/TypeArguments2.kt @@ -11,4 +11,7 @@ class C : A() interface I2 open class B2 -class A2 : B2(), I2 \ No newline at end of file +class A2 : B2(), I2 + +interface I3 +class A3 : I3> \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationMirror.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationMirror.kt index 75f262c53fa..cee86f9e670 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationMirror.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationMirror.kt @@ -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 = getElementValues(false) diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeMethodExecutableElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeMethodExecutableElement.kt index 80d3fbc2fd1..7273bb70ea4 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeMethodExecutableElement.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeMethodExecutableElement.kt @@ -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) + } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt index 400ce6c99c1..fca81b14606 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt @@ -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, 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 accept(v: ElementVisitor, p: P) = v.visitType(this, p) diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeParameterElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeParameterElement.kt index 2cdfee1de8e..61ae4ecd256 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeParameterElement.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeParameterElement.kt @@ -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 accept(v: ElementVisitor, p: P) = v.visitTypeParameter(this, p) diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/internalUtil.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/internalUtil.kt index 57d4eaf437e..e63475f5011 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/internalUtil.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/internalUtil.kt @@ -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 { return annotations } +fun PsiClass.getTypeWithTypeParameters(): PsiClassType { + val elementFactory = JavaPsiFacade.getElementFactory(project) + val params = mutableMapOf() + 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 diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeDeclaredType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeDeclaredType.kt index f046a2d3b74..c16b961c737 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeDeclaredType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeDeclaredType.kt @@ -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): 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): 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 { diff --git a/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt index a8800c86fd8..0e3a58d9735 100644 --- a/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt +++ b/plugins/plugins-tests/tests/org/jetbrains/kotlin/annotation/processing/test/processor/ProcessorTests.kt @@ -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.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", 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>", i3.toString()) } fun testErasureSimple() = test("ErasureSimple", "*") { set, roundEnv, env ->