From f61367df28c576948425351d339a00c3b1aec0fc Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 15 Jul 2016 19:36:16 +0300 Subject: [PATCH] Kapt: Fixes on review (cherry picked from commit be31262) --- .../AnnotationProcessingExtension.kt | 90 ++++++++++--------- .../processing/AnnotationProcessingPlugin.kt | 2 +- .../processing/impl/KotlinElements.kt | 5 +- .../annotation/processing/impl/KotlinFiler.kt | 27 +++--- .../processing/impl/KotlinJavaFileObject.kt | 4 +- .../processing/impl/KotlinMessager.kt | 7 +- .../impl/KotlinProcessingEnvironment.kt | 2 +- .../processing/impl/KotlinRoundEnvironment.kt | 4 +- .../annotation/processing/impl/KotlinTypes.kt | 16 ++-- .../kotlin/java/model/JeAnnotationOwner.kt | 45 +++++++--- .../kotlin/java/model/JeConverter.kt | 19 ++-- .../JeClassInitializerExecutableElement.kt | 4 +- .../elements/JeMethodExecutableElement.kt | 5 +- .../java/model/elements/JePackageElement.kt | 5 +- .../java/model/elements/JeTypeElement.kt | 12 ++- .../java/model/elements/JeVariableElement.kt | 9 +- .../internal/KotlinAnnotationProxyMaker.kt | 41 +++++++-- .../java/model/internal/internalUtil.kt | 7 ++ .../kotlin/java/model/types/JeArrayType.kt | 16 ++-- .../JeClassInitializerExecutableTypeMirror.kt | 6 +- .../kotlin/java/model/types/JeDeclaredType.kt | 52 ++++++----- .../java/model/types/JeIntersectionType.kt | 9 ++ .../types/JeMethodExecutableTypeMirror.kt | 2 +- .../java/model/types/JePrimitiveType.kt | 12 +-- .../kotlin/java/model/types/JePsiType.kt | 18 ---- .../java/model/types/JeTypeVariableType.kt | 13 ++- .../kotlin/java/model/types/JeWildcardType.kt | 30 +++++-- .../kotlin/java/model/types/types.kt | 4 +- 28 files changed, 273 insertions(+), 193 deletions(-) diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingExtension.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingExtension.kt index f4c6f8aaa62..1f8bf80cdab 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingExtension.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingExtension.kt @@ -121,51 +121,59 @@ class AnnotationProcessingExtension( } } -internal class AnalysisContext(val annotationsMap: MutableMap>) - -private fun AnalysisContext.analyzeFiles(files: Collection) { - for (file in files) { - analyzeFile(file) - } -} - -private fun AnalysisContext.analyzeFile(file: KtFile) { - val lightClass = file.findFacadeClass() +internal class AnalysisContext(annotationsMap: MutableMap>) { + private val mutableAnnotationsMap = annotationsMap - if (lightClass != null) { - analyzeDeclaration(lightClass) - } + val annotationsMap: Map> + get() = mutableAnnotationsMap - for (declaration in file.declarations) { - if (declaration !is KtClassOrObject) continue - val clazz = declaration.toLightClass() ?: continue - analyzeDeclaration(clazz) - } -} - -private fun AnalysisContext.analyzeFile(file: PsiJavaFile) { - file.classes.forEach { analyzeDeclaration(it) } -} - -private fun AnalysisContext.analyzeDeclaration(declaration: PsiElement) { - if (declaration !is PsiModifierListOwner) return - - val annotations = declaration.modifierList?.annotations - if (annotations != null) { - for (annotation in annotations) { - val fqName = annotation.qualifiedName ?: continue - annotationsMap.getOrPut(fqName, { mutableListOf() }).add(declaration) + fun analyzeFiles(files: Collection) { + for (file in files) { + analyzeFile(file) } } - - if (declaration is PsiClass) { - declaration.methods.forEach { analyzeDeclaration(it) } - declaration.fields.forEach { analyzeDeclaration(it) } - declaration.innerClasses.forEach { analyzeDeclaration(it) } + + fun analyzeFile(file: KtFile) { + val lightClass = file.findFacadeClass() + + if (lightClass != null) { + analyzeDeclaration(lightClass) + } + + for (declaration in file.declarations) { + if (declaration !is KtClassOrObject) continue + val clazz = declaration.toLightClass() ?: continue + analyzeDeclaration(clazz) + } } - - when (declaration) { - is KtClassOrObject -> declaration.declarations.forEach { analyzeDeclaration(it) } - + + fun analyzeFile(file: PsiJavaFile) { + file.classes.forEach { analyzeDeclaration(it) } + } + + fun analyzeDeclaration(declaration: PsiElement) { + if (declaration !is PsiModifierListOwner) return + + //TODO support inherited annotations + + val annotations = declaration.modifierList?.annotations + if (annotations != null) { + for (annotation in annotations) { + val fqName = annotation.qualifiedName ?: continue + mutableAnnotationsMap.getOrPut(fqName, { mutableListOf() }).add(declaration) + } + } + + if (declaration is PsiClass) { + declaration.methods.forEach { analyzeDeclaration(it) } + declaration.fields.forEach { analyzeDeclaration(it) } + declaration.innerClasses.forEach { analyzeDeclaration(it) } + } + + if (declaration is PsiMethod) { + for (parameter in declaration.parameterList.parameters) { + analyzeDeclaration(parameter) + } + } } } \ No newline at end of file diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt index 753bffd7d0f..e848826114d 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/AnnotationProcessingPlugin.kt @@ -58,7 +58,7 @@ class AnnotationProcessingCommandLineProcessor : CommandLineProcessor { override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID override val pluginOptions: Collection = - listOf(GENERATED_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION) + listOf(GENERATED_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, CLASS_FILES_OUTPUT_DIR_OPTION) override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) { when (option) { 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 665ec769536..f4f47674af1 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 @@ -69,7 +69,8 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc } override fun getBinaryName(type: TypeElement) = JeName((type as JeTypeElement).psi.qualifiedName) - + + //TODO override fun getDocComment(e: Element?) = "" override fun isDeprecated(e: Element?): Boolean { @@ -104,7 +105,7 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc } override fun getAllAnnotationMirrors(e: Element): List { - val annotations = (e as? JeElement)?.annotationMirrors?.toMutableList() ?: return emptyList() + val annotations = (e as? JeElement)?.annotationMirrors?.toMutableList() ?: mutableListOf() if (e is JeTypeElement) { var parent = e.psi.superClass diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinFiler.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinFiler.kt index 59392f1b1bd..c7da1f5f606 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinFiler.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinFiler.kt @@ -29,18 +29,7 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi val PACKAGE_INFO_SUFFIX = ".packageInfo" } - private var dotGeneratedGenerated = false - - private fun createDotGeneratedIfNeeded() { - if (!dotGeneratedGenerated) { - dotGeneratedGenerated = true - File(generatedSourceDir, ".generated").writeText("Generated by kapt2") - } - } - private fun getGeneratedFile(nameCharSequence: CharSequence, extension: String): File { - createDotGeneratedIfNeeded() - val name = nameCharSequence.toString() val isPackageInfo = name.endsWith(PACKAGE_INFO_SUFFIX) val fqName = if (isPackageInfo) name.substring(0, PACKAGE_INFO_SUFFIX.length) else name @@ -59,7 +48,7 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi } override fun getResource(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): FileObject? { - throw UnsupportedOperationException() + return KotlinFileObject(getResourceFile(location, pkg, relativeName)) } override fun createResource( @@ -68,18 +57,22 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi relativeName: CharSequence, vararg originatingElements: Element? ): FileObject? { + val resourceFile = getResourceFile(location, pkg, relativeName) + resourceFile.parentFile.mkdirs() + return KotlinFileObject(resourceFile) + } + + private fun getResourceFile(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): File { val baseDir = when (location) { StandardLocation.CLASS_OUTPUT -> classesOutputDir StandardLocation.SOURCE_OUTPUT -> generatedSourceDir else -> throw IllegalArgumentException("Location is not supported: $location (${location.name})") } - + val targetDir = File(baseDir, pkg.toString().replace('.', '/')) targetDir.mkdirs() - - val targetFile = File(targetDir, relativeName.toString()) - - return KotlinFileObject(targetFile) + + return File(targetDir, relativeName.toString()) } override fun createClassFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject { diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinJavaFileObject.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinJavaFileObject.kt index b8bcc67f68e..a642239edc2 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinJavaFileObject.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinJavaFileObject.kt @@ -49,9 +49,7 @@ abstract class KotlinAbstractFileObject(val file: File) : FileObject { override fun openInputStream() = file.inputStream() - override fun getCharContent(ignoreEncodingErrors: Boolean): CharSequence? { - TODO() - } + override fun getCharContent(ignoreEncodingErrors: Boolean) = file.readText() override fun getLastModified() = file.lastModified() diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinMessager.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinMessager.kt index ca1f2f9629f..d6f5f4396bc 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinMessager.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinMessager.kt @@ -21,6 +21,7 @@ import javax.lang.model.element.AnnotationMirror import javax.lang.model.element.AnnotationValue import javax.lang.model.element.Element import javax.tools.Diagnostic +import javax.tools.Diagnostic.Kind class KotlinMessager : Messager { override fun printMessage(kind: Diagnostic.Kind, msg: CharSequence) = printMessage(kind, msg, null) @@ -32,6 +33,10 @@ class KotlinMessager : Messager { } override fun printMessage(kind: Diagnostic.Kind, msg: CharSequence, e: Element?, a: AnnotationMirror?, v: AnnotationValue?) { - println(msg) + val output = when (kind) { + Kind.ERROR, Kind.WARNING, Kind.MANDATORY_WARNING -> System.err + else -> System.out + } + output.println(msg) } } \ No newline at end of file diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinProcessingEnvironment.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinProcessingEnvironment.kt index c72898a80b7..2e5605ad883 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinProcessingEnvironment.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinProcessingEnvironment.kt @@ -33,7 +33,7 @@ class KotlinProcessingEnvironment( override fun getTypeUtils() = types override fun getMessager() = messager override fun getLocale() = Locale.getDefault() - override fun getSourceVersion() = SourceVersion.RELEASE_6 + override fun getSourceVersion() = SourceVersion.RELEASE_8 override fun getOptions() = options override fun getFiler() = filer } \ No newline at end of file diff --git a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinRoundEnvironment.kt b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinRoundEnvironment.kt index c8f66a62b5e..705372ac6d4 100644 --- a/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinRoundEnvironment.kt +++ b/plugins/annotation-processing/src/org/jetbrains/kotlin/annotation/processing/impl/KotlinRoundEnvironment.kt @@ -17,7 +17,7 @@ package org.jetbrains.kotlin.annotation.processing.impl import org.jetbrains.kotlin.annotation.AnalysisContext -import org.jetbrains.kotlin.java.model.JeConverter +import org.jetbrains.kotlin.java.model.toJeElement import javax.annotation.processing.RoundEnvironment import javax.lang.model.element.Element import javax.lang.model.element.TypeElement @@ -35,7 +35,7 @@ internal class KotlinRoundEnvironment( val declarations = context.annotationsMap[fqName] ?: return emptySet() return hashSetOf().apply { for (declaration in declarations) { - JeConverter.convert(declaration)?.let { add(it) } + declaration.toJeElement()?.let { add(it) } } } } 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 1fd4fbe6bed..b7e666be10b 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 @@ -139,8 +139,12 @@ class KotlinTypes(val javaPsiFacade: JavaPsiFacade, val psiManager: PsiManager, } override fun isSameType(t1: TypeMirror, t2: TypeMirror) = t1 == t2 - - override fun getNoType(kind: TypeKind) = CustomJeNoneType(kind) + + override fun getNoType(kind: TypeKind) = when (kind) { + TypeKind.VOID -> JeVoidType + TypeKind.NONE -> JeNoneType + else -> illegalArg("Must be kind of VOID or NONE, got ${kind.name}") + } override fun getDeclaredType(typeElem: TypeElement, vararg typeArgMirrors: TypeMirror): DeclaredType { val psiClass = (typeElem as JeTypeElement).psi @@ -165,7 +169,7 @@ class KotlinTypes(val javaPsiFacade: JavaPsiFacade, val psiManager: PsiManager, val psiType = createDeclaredType(psiClass, typeArgs) ?: throw IllegalStateException("Can't create declared type ($psiClass, $typeArgs)") - return JeDeclaredType(psiType, psiClass, typeArgumentMirrors = typeArgMirrors.toList()) + return JeDeclaredType(psiType, psiClass) } override fun getDeclaredType( @@ -197,7 +201,7 @@ class KotlinTypes(val javaPsiFacade: JavaPsiFacade, val psiManager: PsiManager, val psiType = createDeclaredType(psiClass, typeArgs) ?: throw IllegalStateException("Can't create declared type ($psiClass, $typeArgs)") - return JeDeclaredType(psiType, psiClass, containing, typeArgMirrors.toList()) + return JeDeclaredType(psiType, psiClass, containing) } override fun asMemberOf(containing: DeclaredType, element: Element): TypeMirror { @@ -258,9 +262,9 @@ private fun illegalArg(text: String? = null): Nothing { } private fun assertKindNot(typeMirror: TypeMirror, vararg kinds: TypeKind): Unit { - if (typeMirror.kind in kinds) illegalArg("type must not be kind of " + typeMirror.kind.name + ", got ${typeMirror.kind}") + if (typeMirror.kind in kinds) illegalArg("type must not be kind of " + kinds.joinToString { it.name } + ", got ${typeMirror.kind.name}") } private fun assertJeType(type: TypeMirror) { - illegalArg("Must be a subclass of JePsiType, got ${type.javaClass.canonicalName}") + illegalArg("Must be a subclass of JePsiType, got ${type.javaClass.name}") } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeAnnotationOwner.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeAnnotationOwner.kt index ce620704039..e782228169c 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeAnnotationOwner.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeAnnotationOwner.kt @@ -30,23 +30,40 @@ interface JeAnnotationOwner : Element { override fun getAnnotationMirrors() = annotationOwner?.annotations?.map { JeAnnotationMirror(it) } ?: emptyList() override fun getAnnotation(annotationClass: Class): A? { - if (!annotationClass.isAnnotation) { - throw IllegalArgumentException("Not an annotation class: " + annotationClass) - } - - val annotationFqName = annotationClass.canonicalName - - val annotation = annotationOwner?.annotations - ?.firstOrNull { it.qualifiedName == annotationFqName } ?: return null - val annotationDeclaration = annotation.nameReferenceElement?.resolve() as? PsiClass ?: return null - - @Suppress("UNCHECKED_CAST") - return KotlinAnnotationProxyMaker(annotation, annotationDeclaration, annotationClass).generate() as? A + return getAnnotationsByType(annotationClass, onlyFirst = true).firstOrNull() } @Suppress("UNCHECKED_CAST") - override fun getAnnotationsByType(annotationType: Class): Array { - return RArray.newInstance(annotationType, 0) as Array + override fun getAnnotationsByType(annotationClass: Class): Array { + val annotations = getAnnotationsByType(annotationClass, onlyFirst = false) + + return (RArray.newInstance(annotationClass, annotations.size) as Array).apply { + annotations.forEachIndexed { i, annotation -> RArray.set(this, i, annotation) } + } + } + + private fun getAnnotationsByType(annotationClass: Class, onlyFirst: Boolean): List { + if (!annotationClass.isAnnotation) { + throw IllegalArgumentException("Not an annotation class: " + annotationClass) + } + + val annotationFqName = annotationClass.canonicalName + + val allAnnotations = annotationOwner?.annotations?.filter { it.qualifiedName == annotationFqName } ?: return emptyList() + if (allAnnotations.isEmpty()) return emptyList() + + val annotations = if (onlyFirst) listOf(allAnnotations.first()) else allAnnotations + + val annotationDeclarations = annotations.map { it to it.nameReferenceElement?.resolve() as? PsiClass }.filter { it.second != null } + + @Suppress("UNCHECKED_CAST") + val annotationProxies = annotationDeclarations.map { + val (annotation, annotationDeclaration) = it + KotlinAnnotationProxyMaker(annotation, annotationDeclaration!!, annotationClass).generate() as? A + } + + @Suppress("UNCHECKED_CAST") + return annotationProxies as List } } diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeConverter.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeConverter.kt index 3f236dc54c8..dfac90d8ce1 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeConverter.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeConverter.kt @@ -19,14 +19,13 @@ package org.jetbrains.kotlin.java.model import com.intellij.psi.* import org.jetbrains.kotlin.java.model.elements.* -object JeConverter { - fun convert(psi: PsiElement?): JeElement? = when (psi) { - null -> null - is PsiPackage -> JePackageElement(psi) - is PsiClass -> JeTypeElement(psi) - is PsiVariable -> JeVariableElement(psi) - is PsiMethod -> JeMethodExecutableElement(psi) - is PsiClassInitializer -> JeClassInitializerExecutableElement(psi) - else -> null - } +// to extension function? +fun PsiElement?.toJeElement(): JeElement? = when (this) { + null -> null + is PsiPackage -> JePackageElement(this) + is PsiClass -> JeTypeElement(this) + is PsiVariable -> JeVariableElement(this) + is PsiMethod -> JeMethodExecutableElement(this) + is PsiClassInitializer -> JeClassInitializerExecutableElement(this) + else -> null } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeClassInitializerExecutableElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeClassInitializerExecutableElement.kt index 720498b9899..9b9563b57dd 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeClassInitializerExecutableElement.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeClassInitializerExecutableElement.kt @@ -17,8 +17,8 @@ package org.jetbrains.kotlin.java.model.elements import com.intellij.psi.PsiClassInitializer -import com.intellij.psi.PsiModifier import org.jetbrains.kotlin.java.model.* +import org.jetbrains.kotlin.java.model.internal.isStatic import org.jetbrains.kotlin.java.model.types.JeClassInitializerExecutableTypeMirror import org.jetbrains.kotlin.java.model.types.JeNoneType import javax.lang.model.element.* @@ -27,7 +27,7 @@ import javax.lang.model.type.TypeMirror class JeClassInitializerExecutableElement(override val psi: PsiClassInitializer) : JeElement(), ExecutableElement, JeNoAnnotations, JeModifierListOwner { - val isStaticInitializer = psi.hasModifierProperty(PsiModifier.STATIC) + val isStaticInitializer = psi.isStatic override fun getEnclosingElement() = psi.containingClass?.let { JeTypeElement(it) } 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 e5514ec30af..062177a5e50 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 @@ -22,6 +22,7 @@ import com.intellij.psi.PsiMethod import com.intellij.psi.PsiModifier import com.intellij.psi.util.PsiTypesUtil import org.jetbrains.kotlin.java.model.* +import org.jetbrains.kotlin.java.model.internal.isStatic import org.jetbrains.kotlin.java.model.types.JeMethodExecutableTypeMirror import org.jetbrains.kotlin.java.model.types.JeNoneType import org.jetbrains.kotlin.java.model.types.toJeType @@ -83,11 +84,11 @@ class JeMethodExecutableElement(override val psi: PsiMethod) : JeElement(), Exec } fun PsiMethod.getReceiverTypeMirror(): TypeMirror { - if (hasModifierProperty(PsiModifier.STATIC)) return JeNoneType + if (isStatic) return JeNoneType if (isConstructor) { val containingClass = containingClass - if (containingClass != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) { + if (containingClass != null && !containingClass.isStatic) { containingClass.containingClass?.let { return PsiTypesUtil.getClassType(it).toJeType(manager) } diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JePackageElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JePackageElement.kt index 31b79e09cf4..e4f98c6eeee 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JePackageElement.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JePackageElement.kt @@ -35,14 +35,15 @@ class JePackageElement(override val psi: PsiPackage) : JeElement(), PackageEleme override fun accept(v: ElementVisitor, p: P) = v.visitPackage(this, p) - override fun isUnnamed() = false + override fun isUnnamed() = psi.name.isNullOrEmpty() override fun getQualifiedName() = JeName(psi.qualifiedName) override fun getEnclosedElements() = psi.classes.map { JeTypeElement(it) } override fun asType() = JePackageTypeMirror - override fun equals(other: Any?): Boolean{ + + override fun equals(other: Any?): Boolean { if (this === other) return true if (other?.javaClass != javaClass) return false 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 8c957009361..0462602a1c6 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 @@ -66,9 +66,13 @@ class JeTypeElement(override val psi: PsiClass) : JeElement(), TypeElement, JeAn fun getAllMembers(): List { val declarations = mutableListOf() - psi.constructors.forEach { declarations += JeMethodExecutableElement(it) } - psi.fields.forEach { declarations += JeVariableElement(it) } - psi.methods.forEach { declarations += JeMethodExecutableElement(it) } + psi.allFields.forEach { declarations += JeVariableElement(it) } + psi.allMethods.forEach { + if (it.isConstructor && it.containingClass != this@JeTypeElement.psi) return@forEach + declarations += JeMethodExecutableElement(it) + } + psi.allInnerClasses.forEach { declarations += JeTypeElement(it) } + psi.initializers.forEach { declarations += JeClassInitializerExecutableElement(it) } return declarations } @@ -92,5 +96,5 @@ class JeTypeElement(override val psi: PsiClass) : JeElement(), TypeElement, JeAn override fun hashCode() = psi.hashCode() - override fun toString() = psi.qualifiedName ?: psi.superClass?.qualifiedName ?: "" + override fun toString() = psi.qualifiedName ?: " extends " + psi.superClass?.qualifiedName ?: "" } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeVariableElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeVariableElement.kt index 8c6a0ab65b5..d5a6cc20a0f 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeVariableElement.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeVariableElement.kt @@ -28,7 +28,11 @@ import javax.lang.model.element.VariableElement class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableElement, JeModifierListOwner, JeAnnotationOwner { override fun getSimpleName() = JeName(psi.name) - override fun getEnclosingElement(): JeTypeElement? { + override fun getEnclosingElement(): JeElement? { + if (psi is PsiParameter) { + (psi.declarationScope as? PsiMethod)?.let { return JeMethodExecutableElement(it) } + } + val containingClass = (psi as? PsiMember)?.containingClass ?: PsiTreeUtil.getParentOfType(psi, PsiClass::class.java) return containingClass?.let { JeTypeElement(it) } } @@ -50,6 +54,7 @@ class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableEl override fun accept(v: ElementVisitor, p: P) = v.visitVariable(this, p) override fun getEnclosedElements() = emptyList() + override val annotationOwner: PsiAnnotationOwner? get() = psi.modifierList @@ -62,5 +67,5 @@ class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableEl override fun hashCode() = psi.hashCode() - override fun toString() = psi.name ?: "" + override fun toString() = psi.name ?: "" } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/KotlinAnnotationProxyMaker.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/KotlinAnnotationProxyMaker.kt index 8626c0d28ef..29384ab387e 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/KotlinAnnotationProxyMaker.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/KotlinAnnotationProxyMaker.kt @@ -30,24 +30,30 @@ import javax.lang.model.type.MirroredTypesException import javax.lang.model.type.TypeMirror class KotlinAnnotationProxyMaker(val annotation: PsiAnnotation, val annotationClass: PsiClass, val annotationType: Class) { - fun generate(): Any { + fun generate(): Annotation { return AnnotationParser.annotationForMap(annotationType, getAllValuesForParser(getAllPsiValues())) } - private fun getAllPsiValues(): List> { - val values = mutableListOf>() + private data class AnnotationParameterData( + val method: PsiAnnotationMethod, + val value: PsiAnnotationMemberValue, + val jMethod: Method) + + private fun getAllPsiValues(): List { + val values = mutableListOf() for (method in annotationClass.methods) { - val jMethod = try { annotationType.getMethod(method.name) } catch (e : NoSuchMethodException) { continue } if (method !is PsiAnnotationMethod) continue if (method.returnType == null) continue + val jMethod = try { annotationType.getMethod(method.name) } catch (e : NoSuchMethodException) { continue } + val value = annotation.findAttributeValue(method.name) ?: method.defaultValue ?: continue - values += Triple(method, value, jMethod) + values += AnnotationParameterData(method, value, jMethod) } return values } - private fun getAllValuesForParser(values: List>): Map { + private fun getAllValuesForParser(values: List): Map { val parserValues = mutableMapOf() val evaluator = JavaPsiFacade.getInstance(annotation.project).constantEvaluationHelper for ((method, value, jMethod) in values) { @@ -70,7 +76,7 @@ private fun getConstantValue( returnType == PsiType.NULL || returnType == PsiType.VOID -> unexpectedType("void") jReturnType == String::class.java -> return calculateConstantValue(psiValue, evaluator) jReturnType == Class::class.java -> { - val type = (psiValue as PsiClassObjectAccessExpression).operand.type.toJeType(manager) + val type = getObjectType(psiValue).toJeType(manager) return MirroredTypeExceptionProxy(type) } jReturnType.isArray -> { @@ -83,7 +89,7 @@ private fun getConstantValue( } if (jComponentType == Class::class.java) { - val typeMirrors = arrayValues.map { (it as PsiClassObjectAccessExpression).operand.type.toJeType(manager) } + val typeMirrors = arrayValues.map { getObjectType(it).toJeType(manager) } return MirroredTypesExceptionProxy(Collections.unmodifiableList(typeMirrors)) } else { val arr = Array.newInstance(jComponentType, arrayValues.size) @@ -103,7 +109,24 @@ private fun getConstantValue( } } -private fun castPrimitiveValue(type: PsiType, value: Any?): Any? = when (type) { +private fun getObjectType(value: PsiAnnotationMemberValue): PsiType { + when (value) { + is PsiClassObjectAccessExpression -> return value.operand.type + is PsiReference -> { + val resolvedElement = value.resolve() + if (resolvedElement is PsiField && resolvedElement.isStatic && resolvedElement.isFinal) { + val initializer = resolvedElement.initializer + if (initializer != null) { + return getObjectType(initializer) + } + } + } + } + + throw IllegalArgumentException("Illegal value type: ${value.javaClass}") +} + +private fun castPrimitiveValue(type: PsiType, value: Any?): Any = when (type) { PsiType.BYTE -> byteValue(value) PsiType.SHORT -> shortValue(value) PsiType.INT -> intValue(value) 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 d6397c56d22..2a80ba35d7b 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 @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.java.model.internal +import com.intellij.psi.PsiModifier import com.intellij.psi.PsiModifier.* import com.intellij.psi.PsiModifierList import com.intellij.psi.PsiModifierListOwner @@ -49,4 +50,10 @@ private fun PsiModifierList.getJavaModifiers(): Set { } } +internal val PsiModifierListOwner.isStatic: Boolean + get() = hasModifierProperty(PsiModifier.STATIC) + +internal val PsiModifierListOwner.isFinal: Boolean + get() = hasModifierProperty(PsiModifier.FINAL) + fun PsiModifierListOwner.getJavaModifiers() = modifierList?.getJavaModifiers() ?: emptySet() \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeArrayType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeArrayType.kt index eea315fd9e4..42c5e717d1f 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeArrayType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeArrayType.kt @@ -27,19 +27,13 @@ class JeArrayType(override val psiType: PsiArrayType, override val psiManager: P override fun accept(v: TypeVisitor, p: P) = v.visitArray(this, p) override fun getComponentType() = psiType.componentType.toJeType(psiManager) - override fun equals(other: Any?): Boolean { + override fun toString() = psiType.getCanonicalText(false) + + override fun equals(other: Any?): Boolean{ if (this === other) return true if (other?.javaClass != javaClass) return false - if (!super.equals(other)) return false - - return psiType == (other as JeArrayType).psiType + return psiType == (other as? JeArrayType)?.psiType } - override fun hashCode(): Int{ - var result = super.hashCode() - result = 31 * result + psiType.hashCode() - return result - } - - override fun toString() = psiType.getCanonicalText(false) + override fun hashCode() = psiType.hashCode() } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeClassInitializerExecutableTypeMirror.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeClassInitializerExecutableTypeMirror.kt index 95b8ae62148..46ad67f4de7 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeClassInitializerExecutableTypeMirror.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeClassInitializerExecutableTypeMirror.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.java.model.types import com.intellij.psi.PsiClassInitializer import com.intellij.psi.PsiManager -import com.intellij.psi.PsiModifier +import org.jetbrains.kotlin.java.model.internal.isStatic import javax.lang.model.type.* class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitializer) : JeTypeMirror, JeTypeWithManager, ExecutableType { @@ -29,7 +29,7 @@ class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitialize override val psiManager: PsiManager get() = initializer.manager - override fun getReturnType() = CustomJeNoneType(TypeKind.VOID) + override fun getReturnType() = JeVoidType override fun getReceiverType() = JeNoneType @@ -40,7 +40,7 @@ class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitialize override fun getTypeVariables() = emptyList() override fun toString() = (initializer.containingClass?.qualifiedName?.let { it + "." } ?: "") + - (if (initializer.hasModifierProperty(PsiModifier.STATIC)) "" else "") + (if (initializer.isStatic) "" else "") override fun equals(other: Any?): Boolean { if (this === other) return true 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 bf0bf6dd510..649ce6796aa 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 @@ -17,45 +17,61 @@ package org.jetbrains.kotlin.java.model.types import com.intellij.pom.java.LanguageLevel -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiClassType -import com.intellij.psi.PsiManager -import com.intellij.psi.PsiType +import com.intellij.psi.* import com.intellij.psi.impl.light.LightClassReferenceExpression import com.intellij.psi.impl.source.PsiClassReferenceType import com.intellij.psi.util.PsiTypesUtil import org.jetbrains.kotlin.java.model.elements.JeTypeElement +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 params = typeArgs.toTypedArray() - val text = (psiClass.name ?: return null) + typeArgs.joinToString(prefix = "<", postfix = ">") + 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() = params + override fun getTypeParameters() = args }, LanguageLevel.JDK_1_8) } class JeDeclaredType( - override val psiType: PsiClassType, + override val psiType: PsiClassType, val psiClass: PsiClass, - val enclosingDeclaredType: DeclaredType? = null, - val typeArgumentMirrors: List? = null + val enclosingDeclaredType: DeclaredType? = null ) : JePsiType(), JeTypeWithManager, DeclaredType { override fun getKind() = TypeKind.DECLARED + override fun accept(v: TypeVisitor, p: P) = v.visitDeclared(this, p) override val psiManager: PsiManager get() = psiClass.manager - override fun getTypeArguments() = typeArgumentMirrors ?: psiType.parameters.map { it.toJeType(psiManager) } + override fun getTypeArguments(): List { + if (psiType.isRaw) return emptyList() + + return when (psiType) { + is PsiClassReferenceType -> { + val substitutor = psiType.resolveGenerics().substitutor + if (substitutor.isValid) { + substitutor.substitutionMap.map { it.value.toJeType(psiManager) } + } + else { + emptyList() + } + } + else -> emptyList() + } + } override fun asElement() = JeTypeElement(psiClass) override fun getEnclosingType(): TypeMirror { + if (!psiClass.isStatic) return JeNoneType + if (enclosingDeclaredType != null) return enclosingDeclaredType + val psiClass = psiClass.containingClass ?: return JeNoneType return PsiTypesUtil.getClassType(psiClass).toJeType(psiManager) } @@ -63,16 +79,10 @@ class JeDeclaredType( override fun equals(other: Any?): Boolean{ if (this === other) return true if (other?.javaClass != javaClass) return false - if (!super.equals(other)) return false - - return psiType == (other as JeDeclaredType).psiType + return psiType == (other as? JeDeclaredType)?.psiType } - override fun hashCode(): Int { - var result = super.hashCode() - result = 31 * result + psiType.hashCode() - return result - } - - override fun toString(): String = psiType.getCanonicalText(false) + override fun hashCode() = psiType.hashCode() + + override fun toString() = psiType.getCanonicalText(false) } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeIntersectionType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeIntersectionType.kt index 437920d1587..e558635d489 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeIntersectionType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeIntersectionType.kt @@ -28,5 +28,14 @@ class JeIntersectionType( ) : JePsiType(), JeTypeWithManager, IntersectionType { override fun getKind() = TypeKind.INTERSECTION override fun accept(v: TypeVisitor, p: P) = v.visitIntersection(this, p) + override fun getBounds() = psiType.superTypes.map { it.toJeType(psiManager) } + + override fun equals(other: Any?): Boolean{ + if (this === other) return true + if (other?.javaClass != javaClass) return false + return psiType == (other as? JeIntersectionType)?.psiType + } + + override fun hashCode() = psiType.hashCode() } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt index b54abbf0825..ad7a3d8a22a 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt @@ -36,7 +36,7 @@ class JeMethodExecutableTypeMirror( override fun accept(v: TypeVisitor, p: P) = v.visitExecutable(this, p) - override fun getReturnType() = (returnType ?: psi.returnType)?.let { it.toJeType(psi.manager) } ?: CustomJeNoneType(TypeKind.VOID) + override fun getReturnType() = (returnType ?: psi.returnType)?.let { it.toJeType(psi.manager) } ?: JeVoidType override fun getReceiverType() = psi.getReceiverTypeMirror() diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePrimitiveType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePrimitiveType.kt index cf425581691..a11042e816e 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePrimitiveType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePrimitiveType.kt @@ -40,17 +40,11 @@ class JePrimitiveType(override val psiType: PsiPrimitiveType) : JePsiType(), Pri override fun toString() = psiType.canonicalText - override fun equals(other: Any?): Boolean { + override fun equals(other: Any?): Boolean{ if (this === other) return true if (other?.javaClass != javaClass) return false - if (!super.equals(other)) return false - - return psiType === (other as JePrimitiveType).psiType + return psiType == (other as? JePrimitiveType)?.psiType } - override fun hashCode(): Int{ - var result = super.hashCode() - result = 31 * result + psiType.hashCode() - return result - } + override fun hashCode() = psiType.hashCode() } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePsiType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePsiType.kt index 4cda56b2da7..3b7c7222338 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePsiType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePsiType.kt @@ -20,22 +20,4 @@ import com.intellij.psi.PsiType abstract class JePsiType : JeTypeMirror { abstract val psiType: PsiType - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other?.javaClass != javaClass) return false - - other as JePsiType - - if (kind != other.kind) return false - if (psiType != other.psiType) return false - - return true - } - - override fun hashCode(): Int{ - var result = kind.hashCode() - result = 31 * result + psiType.hashCode() - return result - } } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt index ad11a1987e0..197eff47a91 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt @@ -16,9 +16,9 @@ package org.jetbrains.kotlin.java.model.types -import org.jetbrains.kotlin.java.model.JeConverter import org.jetbrains.kotlin.java.model.elements.JeTypeParameterElement import com.intellij.psi.* +import org.jetbrains.kotlin.java.model.toJeElement import javax.lang.model.type.TypeKind import javax.lang.model.type.TypeMirror import javax.lang.model.type.TypeVariable @@ -29,6 +29,7 @@ class JeTypeVariableType( val parameter: PsiTypeParameter ) : JePsiType(), JeTypeWithManager, TypeVariable { override fun getKind() = TypeKind.TYPEVAR + override fun accept(v: TypeVisitor, p: P) = v.visitTypeVariable(this, p) override val psiManager: PsiManager @@ -48,5 +49,13 @@ class JeTypeVariableType( } } - override fun asElement() = JeTypeParameterElement(parameter, JeConverter.convert(parameter.owner)) + override fun asElement() = JeTypeParameterElement(parameter, parameter.owner.toJeElement()) + + override fun equals(other: Any?): Boolean{ + if (this === other) return true + if (other?.javaClass != javaClass) return false + return psiType == (other as? JeTypeVariableType)?.psiType + } + + override fun hashCode() = psiType.hashCode() } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeWildcardType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeWildcardType.kt index 9facfd0de5e..717f3db09e8 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeWildcardType.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeWildcardType.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.java.model.types +import com.intellij.psi.PsiCapturedWildcardType import com.intellij.psi.PsiManager import com.intellij.psi.PsiWildcardType import javax.lang.model.type.TypeKind @@ -32,17 +33,30 @@ class JeWildcardType(override val psiType: PsiWildcardType) : JePsiType(), JeTyp override val psiManager: PsiManager get() = psiType.manager + override fun equals(other: Any?): Boolean{ + if (this === other) return true + if (other?.javaClass != javaClass) return false + return psiType == (other as? JeWildcardType)?.psiType + } + + override fun hashCode() = psiType.hashCode() +} + +class JeCapturedWildcardType( + override val psiType: PsiCapturedWildcardType, + override val psiManager: PsiManager +) : JePsiType(), JeTypeWithManager, WildcardType { + override fun getKind() = TypeKind.WILDCARD + override fun accept(v: TypeVisitor, p: P) = v.visitWildcard(this, p) + + override fun getSuperBound() = psiType.lowerBound.toJeType(psiManager) + override fun getExtendsBound() = psiType.upperBound.toJeType(psiManager) + override fun equals(other: Any?): Boolean { if (this === other) return true if (other?.javaClass != javaClass) return false - if (!super.equals(other)) return false - - return psiType == (other as JeWildcardType).psiType + return psiType == (other as? JeWildcardType)?.psiType } - override fun hashCode(): Int { - var result = super.hashCode() - result = 31 * result + psiType.hashCode() - return result - } + override fun hashCode() = psiType.hashCode() } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/types.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/types.kt index 1af5b230465..35f533a50b4 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/types.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/types.kt @@ -25,7 +25,8 @@ import java.lang.reflect.Array as RArray private val PSI_PRIMITIVES_MAP = listOf( PsiType.BYTE, PsiType.CHAR, PsiType.DOUBLE, PsiType.FLOAT, PsiType.INT, PsiType.LONG, - PsiType.SHORT, PsiType.BOOLEAN).associate { it to JePrimitiveType(it) } + PsiType.SHORT, PsiType.BOOLEAN +).associate { it to JePrimitiveType(it) } private val TYPE_KIND_TO_PSI_PRIMITIVE_MAP = mapOf( TypeKind.BYTE to PsiType.BYTE, @@ -47,6 +48,7 @@ fun PsiType.toJeType(manager: PsiManager): TypeMirror = when (this) { is PsiPrimitiveType -> PSI_PRIMITIVES_MAP[this] ?: JeErrorType is PsiArrayType -> JeArrayType(this, manager) is PsiWildcardType -> JeWildcardType(this) + is PsiCapturedWildcardType -> JeCapturedWildcardType(this, manager) is PsiClassType -> { val resolvedClass = this.resolve() when (resolvedClass) {