Kapt: Fixes on review
(cherry picked from commit be31262)
This commit is contained in:
committed by
Yan Zhulanow
parent
5b8e6abdeb
commit
f61367df28
+49
-41
@@ -121,51 +121,59 @@ class AnnotationProcessingExtension(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class AnalysisContext(val annotationsMap: MutableMap<String, MutableList<PsiModifierListOwner>>)
|
internal class AnalysisContext(annotationsMap: MutableMap<String, MutableList<PsiModifierListOwner>>) {
|
||||||
|
private val mutableAnnotationsMap = annotationsMap
|
||||||
private fun AnalysisContext.analyzeFiles(files: Collection<KtFile>) {
|
|
||||||
for (file in files) {
|
|
||||||
analyzeFile(file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun AnalysisContext.analyzeFile(file: KtFile) {
|
|
||||||
val lightClass = file.findFacadeClass()
|
|
||||||
|
|
||||||
if (lightClass != null) {
|
val annotationsMap: Map<String, List<PsiModifierListOwner>>
|
||||||
analyzeDeclaration(lightClass)
|
get() = mutableAnnotationsMap
|
||||||
}
|
|
||||||
|
|
||||||
for (declaration in file.declarations) {
|
fun analyzeFiles(files: Collection<KtFile>) {
|
||||||
if (declaration !is KtClassOrObject) continue
|
for (file in files) {
|
||||||
val clazz = declaration.toLightClass() ?: continue
|
analyzeFile(file)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (declaration is PsiClass) {
|
fun analyzeFile(file: KtFile) {
|
||||||
declaration.methods.forEach { analyzeDeclaration(it) }
|
val lightClass = file.findFacadeClass()
|
||||||
declaration.fields.forEach { analyzeDeclaration(it) }
|
|
||||||
declaration.innerClasses.forEach { analyzeDeclaration(it) }
|
if (lightClass != null) {
|
||||||
|
analyzeDeclaration(lightClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (declaration in file.declarations) {
|
||||||
|
if (declaration !is KtClassOrObject) continue
|
||||||
|
val clazz = declaration.toLightClass() ?: continue
|
||||||
|
analyzeDeclaration(clazz)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
when (declaration) {
|
fun analyzeFile(file: PsiJavaFile) {
|
||||||
is KtClassOrObject -> declaration.declarations.forEach { analyzeDeclaration(it) }
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -58,7 +58,7 @@ class AnnotationProcessingCommandLineProcessor : CommandLineProcessor {
|
|||||||
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
|
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
|
||||||
|
|
||||||
override val pluginOptions: Collection<CliOption> =
|
override val pluginOptions: Collection<CliOption> =
|
||||||
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) {
|
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
||||||
when (option) {
|
when (option) {
|
||||||
|
|||||||
+3
-2
@@ -69,7 +69,8 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getBinaryName(type: TypeElement) = JeName((type as JeTypeElement).psi.qualifiedName)
|
override fun getBinaryName(type: TypeElement) = JeName((type as JeTypeElement).psi.qualifiedName)
|
||||||
|
|
||||||
|
//TODO
|
||||||
override fun getDocComment(e: Element?) = ""
|
override fun getDocComment(e: Element?) = ""
|
||||||
|
|
||||||
override fun isDeprecated(e: Element?): Boolean {
|
override fun isDeprecated(e: Element?): Boolean {
|
||||||
@@ -104,7 +105,7 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getAllAnnotationMirrors(e: Element): List<AnnotationMirror> {
|
override fun getAllAnnotationMirrors(e: Element): List<AnnotationMirror> {
|
||||||
val annotations = (e as? JeElement)?.annotationMirrors?.toMutableList() ?: return emptyList()
|
val annotations = (e as? JeElement)?.annotationMirrors?.toMutableList() ?: mutableListOf()
|
||||||
|
|
||||||
if (e is JeTypeElement) {
|
if (e is JeTypeElement) {
|
||||||
var parent = e.psi.superClass
|
var parent = e.psi.superClass
|
||||||
|
|||||||
+10
-17
@@ -29,18 +29,7 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi
|
|||||||
val PACKAGE_INFO_SUFFIX = ".packageInfo"
|
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 {
|
private fun getGeneratedFile(nameCharSequence: CharSequence, extension: String): File {
|
||||||
createDotGeneratedIfNeeded()
|
|
||||||
|
|
||||||
val name = nameCharSequence.toString()
|
val name = nameCharSequence.toString()
|
||||||
val isPackageInfo = name.endsWith(PACKAGE_INFO_SUFFIX)
|
val isPackageInfo = name.endsWith(PACKAGE_INFO_SUFFIX)
|
||||||
val fqName = if (isPackageInfo) name.substring(0, PACKAGE_INFO_SUFFIX.length) else name
|
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? {
|
override fun getResource(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): FileObject? {
|
||||||
throw UnsupportedOperationException()
|
return KotlinFileObject(getResourceFile(location, pkg, relativeName))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createResource(
|
override fun createResource(
|
||||||
@@ -68,18 +57,22 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi
|
|||||||
relativeName: CharSequence,
|
relativeName: CharSequence,
|
||||||
vararg originatingElements: Element?
|
vararg originatingElements: Element?
|
||||||
): FileObject? {
|
): 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) {
|
val baseDir = when (location) {
|
||||||
StandardLocation.CLASS_OUTPUT -> classesOutputDir
|
StandardLocation.CLASS_OUTPUT -> classesOutputDir
|
||||||
StandardLocation.SOURCE_OUTPUT -> generatedSourceDir
|
StandardLocation.SOURCE_OUTPUT -> generatedSourceDir
|
||||||
else -> throw IllegalArgumentException("Location is not supported: $location (${location.name})")
|
else -> throw IllegalArgumentException("Location is not supported: $location (${location.name})")
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetDir = File(baseDir, pkg.toString().replace('.', '/'))
|
val targetDir = File(baseDir, pkg.toString().replace('.', '/'))
|
||||||
targetDir.mkdirs()
|
targetDir.mkdirs()
|
||||||
|
|
||||||
val targetFile = File(targetDir, relativeName.toString())
|
return File(targetDir, relativeName.toString())
|
||||||
|
|
||||||
return KotlinFileObject(targetFile)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createClassFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
|
override fun createClassFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
|
||||||
|
|||||||
+1
-3
@@ -49,9 +49,7 @@ abstract class KotlinAbstractFileObject(val file: File) : FileObject {
|
|||||||
|
|
||||||
override fun openInputStream() = file.inputStream()
|
override fun openInputStream() = file.inputStream()
|
||||||
|
|
||||||
override fun getCharContent(ignoreEncodingErrors: Boolean): CharSequence? {
|
override fun getCharContent(ignoreEncodingErrors: Boolean) = file.readText()
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getLastModified() = file.lastModified()
|
override fun getLastModified() = file.lastModified()
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -21,6 +21,7 @@ import javax.lang.model.element.AnnotationMirror
|
|||||||
import javax.lang.model.element.AnnotationValue
|
import javax.lang.model.element.AnnotationValue
|
||||||
import javax.lang.model.element.Element
|
import javax.lang.model.element.Element
|
||||||
import javax.tools.Diagnostic
|
import javax.tools.Diagnostic
|
||||||
|
import javax.tools.Diagnostic.Kind
|
||||||
|
|
||||||
class KotlinMessager : Messager {
|
class KotlinMessager : Messager {
|
||||||
override fun printMessage(kind: Diagnostic.Kind, msg: CharSequence) = printMessage(kind, msg, null)
|
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?) {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -33,7 +33,7 @@ class KotlinProcessingEnvironment(
|
|||||||
override fun getTypeUtils() = types
|
override fun getTypeUtils() = types
|
||||||
override fun getMessager() = messager
|
override fun getMessager() = messager
|
||||||
override fun getLocale() = Locale.getDefault()
|
override fun getLocale() = Locale.getDefault()
|
||||||
override fun getSourceVersion() = SourceVersion.RELEASE_6
|
override fun getSourceVersion() = SourceVersion.RELEASE_8
|
||||||
override fun getOptions() = options
|
override fun getOptions() = options
|
||||||
override fun getFiler() = filer
|
override fun getFiler() = filer
|
||||||
}
|
}
|
||||||
+2
-2
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.annotation.processing.impl
|
package org.jetbrains.kotlin.annotation.processing.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.annotation.AnalysisContext
|
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.annotation.processing.RoundEnvironment
|
||||||
import javax.lang.model.element.Element
|
import javax.lang.model.element.Element
|
||||||
import javax.lang.model.element.TypeElement
|
import javax.lang.model.element.TypeElement
|
||||||
@@ -35,7 +35,7 @@ internal class KotlinRoundEnvironment(
|
|||||||
val declarations = context.annotationsMap[fqName] ?: return emptySet()
|
val declarations = context.annotationsMap[fqName] ?: return emptySet()
|
||||||
return hashSetOf<Element>().apply {
|
return hashSetOf<Element>().apply {
|
||||||
for (declaration in declarations) {
|
for (declaration in declarations) {
|
||||||
JeConverter.convert(declaration)?.let { add(it) }
|
declaration.toJeElement()?.let { add(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-6
@@ -139,8 +139,12 @@ class KotlinTypes(val javaPsiFacade: JavaPsiFacade, val psiManager: PsiManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun isSameType(t1: TypeMirror, t2: TypeMirror) = t1 == t2
|
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 {
|
override fun getDeclaredType(typeElem: TypeElement, vararg typeArgMirrors: TypeMirror): DeclaredType {
|
||||||
val psiClass = (typeElem as JeTypeElement).psi
|
val psiClass = (typeElem as JeTypeElement).psi
|
||||||
@@ -165,7 +169,7 @@ class KotlinTypes(val javaPsiFacade: JavaPsiFacade, val psiManager: PsiManager,
|
|||||||
|
|
||||||
val psiType = createDeclaredType(psiClass, typeArgs) ?:
|
val psiType = createDeclaredType(psiClass, typeArgs) ?:
|
||||||
throw IllegalStateException("Can't create declared type ($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(
|
override fun getDeclaredType(
|
||||||
@@ -197,7 +201,7 @@ class KotlinTypes(val javaPsiFacade: JavaPsiFacade, val psiManager: PsiManager,
|
|||||||
|
|
||||||
val psiType = createDeclaredType(psiClass, typeArgs) ?:
|
val psiType = createDeclaredType(psiClass, typeArgs) ?:
|
||||||
throw IllegalStateException("Can't create declared type ($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 {
|
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 {
|
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) {
|
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}")
|
||||||
}
|
}
|
||||||
+31
-14
@@ -30,23 +30,40 @@ interface JeAnnotationOwner : Element {
|
|||||||
override fun getAnnotationMirrors() = annotationOwner?.annotations?.map { JeAnnotationMirror(it) } ?: emptyList()
|
override fun getAnnotationMirrors() = annotationOwner?.annotations?.map { JeAnnotationMirror(it) } ?: emptyList()
|
||||||
|
|
||||||
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>): A? {
|
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>): A? {
|
||||||
if (!annotationClass.isAnnotation) {
|
return getAnnotationsByType(annotationClass, onlyFirst = true).firstOrNull()
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun <A : Annotation?> getAnnotationsByType(annotationType: Class<A>): Array<A> {
|
override fun <A : Annotation> getAnnotationsByType(annotationClass: Class<A>): Array<A> {
|
||||||
return RArray.newInstance(annotationType, 0) as Array<A>
|
val annotations = getAnnotationsByType(annotationClass, onlyFirst = false)
|
||||||
|
|
||||||
|
return (RArray.newInstance(annotationClass, annotations.size) as Array<A>).apply {
|
||||||
|
annotations.forEachIndexed { i, annotation -> RArray.set(this, i, annotation) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <A : Annotation> getAnnotationsByType(annotationClass: Class<A>, onlyFirst: Boolean): List<A> {
|
||||||
|
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<A>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,14 +19,13 @@ package org.jetbrains.kotlin.java.model
|
|||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import org.jetbrains.kotlin.java.model.elements.*
|
import org.jetbrains.kotlin.java.model.elements.*
|
||||||
|
|
||||||
object JeConverter {
|
// to extension function?
|
||||||
fun convert(psi: PsiElement?): JeElement? = when (psi) {
|
fun PsiElement?.toJeElement(): JeElement? = when (this) {
|
||||||
null -> null
|
null -> null
|
||||||
is PsiPackage -> JePackageElement(psi)
|
is PsiPackage -> JePackageElement(this)
|
||||||
is PsiClass -> JeTypeElement(psi)
|
is PsiClass -> JeTypeElement(this)
|
||||||
is PsiVariable -> JeVariableElement(psi)
|
is PsiVariable -> JeVariableElement(this)
|
||||||
is PsiMethod -> JeMethodExecutableElement(psi)
|
is PsiMethod -> JeMethodExecutableElement(this)
|
||||||
is PsiClassInitializer -> JeClassInitializerExecutableElement(psi)
|
is PsiClassInitializer -> JeClassInitializerExecutableElement(this)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -17,8 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.java.model.elements
|
package org.jetbrains.kotlin.java.model.elements
|
||||||
|
|
||||||
import com.intellij.psi.PsiClassInitializer
|
import com.intellij.psi.PsiClassInitializer
|
||||||
import com.intellij.psi.PsiModifier
|
|
||||||
import org.jetbrains.kotlin.java.model.*
|
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.JeClassInitializerExecutableTypeMirror
|
||||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||||
import javax.lang.model.element.*
|
import javax.lang.model.element.*
|
||||||
@@ -27,7 +27,7 @@ import javax.lang.model.type.TypeMirror
|
|||||||
class JeClassInitializerExecutableElement(override val psi: PsiClassInitializer) : JeElement(),
|
class JeClassInitializerExecutableElement(override val psi: PsiClassInitializer) : JeElement(),
|
||||||
ExecutableElement, JeNoAnnotations, JeModifierListOwner
|
ExecutableElement, JeNoAnnotations, JeModifierListOwner
|
||||||
{
|
{
|
||||||
val isStaticInitializer = psi.hasModifierProperty(PsiModifier.STATIC)
|
val isStaticInitializer = psi.isStatic
|
||||||
|
|
||||||
override fun getEnclosingElement() = psi.containingClass?.let { JeTypeElement(it) }
|
override fun getEnclosingElement() = psi.containingClass?.let { JeTypeElement(it) }
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiMethod
|
|||||||
import com.intellij.psi.PsiModifier
|
import com.intellij.psi.PsiModifier
|
||||||
import com.intellij.psi.util.PsiTypesUtil
|
import com.intellij.psi.util.PsiTypesUtil
|
||||||
import org.jetbrains.kotlin.java.model.*
|
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.JeMethodExecutableTypeMirror
|
||||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||||
@@ -83,11 +84,11 @@ class JeMethodExecutableElement(override val psi: PsiMethod) : JeElement(), Exec
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun PsiMethod.getReceiverTypeMirror(): TypeMirror {
|
fun PsiMethod.getReceiverTypeMirror(): TypeMirror {
|
||||||
if (hasModifierProperty(PsiModifier.STATIC)) return JeNoneType
|
if (isStatic) return JeNoneType
|
||||||
|
|
||||||
if (isConstructor) {
|
if (isConstructor) {
|
||||||
val containingClass = containingClass
|
val containingClass = containingClass
|
||||||
if (containingClass != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
|
if (containingClass != null && !containingClass.isStatic) {
|
||||||
containingClass.containingClass?.let {
|
containingClass.containingClass?.let {
|
||||||
return PsiTypesUtil.getClassType(it).toJeType(manager)
|
return PsiTypesUtil.getClassType(it).toJeType(manager)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -35,14 +35,15 @@ class JePackageElement(override val psi: PsiPackage) : JeElement(), PackageEleme
|
|||||||
|
|
||||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitPackage(this, p)
|
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitPackage(this, p)
|
||||||
|
|
||||||
override fun isUnnamed() = false
|
override fun isUnnamed() = psi.name.isNullOrEmpty()
|
||||||
|
|
||||||
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
||||||
|
|
||||||
override fun getEnclosedElements() = psi.classes.map { JeTypeElement(it) }
|
override fun getEnclosedElements() = psi.classes.map { JeTypeElement(it) }
|
||||||
|
|
||||||
override fun asType() = JePackageTypeMirror
|
override fun asType() = JePackageTypeMirror
|
||||||
override fun equals(other: Any?): Boolean{
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other?.javaClass != javaClass) return false
|
if (other?.javaClass != javaClass) return false
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -66,9 +66,13 @@ class JeTypeElement(override val psi: PsiClass) : JeElement(), TypeElement, JeAn
|
|||||||
|
|
||||||
fun getAllMembers(): List<Element> {
|
fun getAllMembers(): List<Element> {
|
||||||
val declarations = mutableListOf<Element>()
|
val declarations = mutableListOf<Element>()
|
||||||
psi.constructors.forEach { declarations += JeMethodExecutableElement(it) }
|
psi.allFields.forEach { declarations += JeVariableElement(it) }
|
||||||
psi.fields.forEach { declarations += JeVariableElement(it) }
|
psi.allMethods.forEach {
|
||||||
psi.methods.forEach { declarations += JeMethodExecutableElement(it) }
|
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
|
return declarations
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,5 +96,5 @@ class JeTypeElement(override val psi: PsiClass) : JeElement(), TypeElement, JeAn
|
|||||||
|
|
||||||
override fun hashCode() = psi.hashCode()
|
override fun hashCode() = psi.hashCode()
|
||||||
|
|
||||||
override fun toString() = psi.qualifiedName ?: psi.superClass?.qualifiedName ?: "<unnamed>"
|
override fun toString() = psi.qualifiedName ?: "<anonymous> extends " + psi.superClass?.qualifiedName ?: "<unnamed>"
|
||||||
}
|
}
|
||||||
+7
-2
@@ -28,7 +28,11 @@ import javax.lang.model.element.VariableElement
|
|||||||
class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableElement, JeModifierListOwner, JeAnnotationOwner {
|
class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||||
override fun getSimpleName() = JeName(psi.name)
|
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)
|
val containingClass = (psi as? PsiMember)?.containingClass ?: PsiTreeUtil.getParentOfType(psi, PsiClass::class.java)
|
||||||
return containingClass?.let { JeTypeElement(it) }
|
return containingClass?.let { JeTypeElement(it) }
|
||||||
}
|
}
|
||||||
@@ -50,6 +54,7 @@ class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableEl
|
|||||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitVariable(this, p)
|
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitVariable(this, p)
|
||||||
|
|
||||||
override fun getEnclosedElements() = emptyList<Element>()
|
override fun getEnclosedElements() = emptyList<Element>()
|
||||||
|
|
||||||
override val annotationOwner: PsiAnnotationOwner?
|
override val annotationOwner: PsiAnnotationOwner?
|
||||||
get() = psi.modifierList
|
get() = psi.modifierList
|
||||||
|
|
||||||
@@ -62,5 +67,5 @@ class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableEl
|
|||||||
|
|
||||||
override fun hashCode() = psi.hashCode()
|
override fun hashCode() = psi.hashCode()
|
||||||
|
|
||||||
override fun toString() = psi.name ?: "<unnamed>"
|
override fun toString() = psi.name ?: "<unnamed variable>"
|
||||||
}
|
}
|
||||||
+32
-9
@@ -30,24 +30,30 @@ import javax.lang.model.type.MirroredTypesException
|
|||||||
import javax.lang.model.type.TypeMirror
|
import javax.lang.model.type.TypeMirror
|
||||||
|
|
||||||
class KotlinAnnotationProxyMaker(val annotation: PsiAnnotation, val annotationClass: PsiClass, val annotationType: Class<out Annotation>) {
|
class KotlinAnnotationProxyMaker(val annotation: PsiAnnotation, val annotationClass: PsiClass, val annotationType: Class<out Annotation>) {
|
||||||
fun generate(): Any {
|
fun generate(): Annotation {
|
||||||
return AnnotationParser.annotationForMap(annotationType, getAllValuesForParser(getAllPsiValues()))
|
return AnnotationParser.annotationForMap(annotationType, getAllValuesForParser(getAllPsiValues()))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAllPsiValues(): List<Triple<PsiAnnotationMethod, PsiAnnotationMemberValue, Method>> {
|
private data class AnnotationParameterData(
|
||||||
val values = mutableListOf<Triple<PsiAnnotationMethod, PsiAnnotationMemberValue, Method>>()
|
val method: PsiAnnotationMethod,
|
||||||
|
val value: PsiAnnotationMemberValue,
|
||||||
|
val jMethod: Method)
|
||||||
|
|
||||||
|
private fun getAllPsiValues(): List<AnnotationParameterData> {
|
||||||
|
val values = mutableListOf<AnnotationParameterData>()
|
||||||
for (method in annotationClass.methods) {
|
for (method in annotationClass.methods) {
|
||||||
val jMethod = try { annotationType.getMethod(method.name) } catch (e : NoSuchMethodException) { continue }
|
|
||||||
if (method !is PsiAnnotationMethod) continue
|
if (method !is PsiAnnotationMethod) continue
|
||||||
if (method.returnType == null) 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
|
val value = annotation.findAttributeValue(method.name) ?: method.defaultValue ?: continue
|
||||||
values += Triple(method, value, jMethod)
|
values += AnnotationParameterData(method, value, jMethod)
|
||||||
}
|
}
|
||||||
return values
|
return values
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAllValuesForParser(values: List<Triple<PsiAnnotationMethod, PsiAnnotationMemberValue, Method>>): Map<String, Any?> {
|
private fun getAllValuesForParser(values: List<AnnotationParameterData>): Map<String, Any?> {
|
||||||
val parserValues = mutableMapOf<String, Any?>()
|
val parserValues = mutableMapOf<String, Any?>()
|
||||||
val evaluator = JavaPsiFacade.getInstance(annotation.project).constantEvaluationHelper
|
val evaluator = JavaPsiFacade.getInstance(annotation.project).constantEvaluationHelper
|
||||||
for ((method, value, jMethod) in values) {
|
for ((method, value, jMethod) in values) {
|
||||||
@@ -70,7 +76,7 @@ private fun getConstantValue(
|
|||||||
returnType == PsiType.NULL || returnType == PsiType.VOID -> unexpectedType("void")
|
returnType == PsiType.NULL || returnType == PsiType.VOID -> unexpectedType("void")
|
||||||
jReturnType == String::class.java -> return calculateConstantValue(psiValue, evaluator)
|
jReturnType == String::class.java -> return calculateConstantValue(psiValue, evaluator)
|
||||||
jReturnType == Class::class.java -> {
|
jReturnType == Class::class.java -> {
|
||||||
val type = (psiValue as PsiClassObjectAccessExpression).operand.type.toJeType(manager)
|
val type = getObjectType(psiValue).toJeType(manager)
|
||||||
return MirroredTypeExceptionProxy(type)
|
return MirroredTypeExceptionProxy(type)
|
||||||
}
|
}
|
||||||
jReturnType.isArray -> {
|
jReturnType.isArray -> {
|
||||||
@@ -83,7 +89,7 @@ private fun getConstantValue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (jComponentType == Class::class.java) {
|
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))
|
return MirroredTypesExceptionProxy(Collections.unmodifiableList(typeMirrors))
|
||||||
} else {
|
} else {
|
||||||
val arr = Array.newInstance(jComponentType, arrayValues.size)
|
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.BYTE -> byteValue(value)
|
||||||
PsiType.SHORT -> shortValue(value)
|
PsiType.SHORT -> shortValue(value)
|
||||||
PsiType.INT -> intValue(value)
|
PsiType.INT -> intValue(value)
|
||||||
|
|||||||
+7
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.java.model.internal
|
package org.jetbrains.kotlin.java.model.internal
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiModifier
|
||||||
import com.intellij.psi.PsiModifier.*
|
import com.intellij.psi.PsiModifier.*
|
||||||
import com.intellij.psi.PsiModifierList
|
import com.intellij.psi.PsiModifierList
|
||||||
import com.intellij.psi.PsiModifierListOwner
|
import com.intellij.psi.PsiModifierListOwner
|
||||||
@@ -49,4 +50,10 @@ private fun PsiModifierList.getJavaModifiers(): Set<Modifier> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val PsiModifierListOwner.isStatic: Boolean
|
||||||
|
get() = hasModifierProperty(PsiModifier.STATIC)
|
||||||
|
|
||||||
|
internal val PsiModifierListOwner.isFinal: Boolean
|
||||||
|
get() = hasModifierProperty(PsiModifier.FINAL)
|
||||||
|
|
||||||
fun PsiModifierListOwner.getJavaModifiers() = modifierList?.getJavaModifiers() ?: emptySet()
|
fun PsiModifierListOwner.getJavaModifiers() = modifierList?.getJavaModifiers() ?: emptySet()
|
||||||
+5
-11
@@ -27,19 +27,13 @@ class JeArrayType(override val psiType: PsiArrayType, override val psiManager: P
|
|||||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitArray(this, p)
|
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitArray(this, p)
|
||||||
override fun getComponentType() = psiType.componentType.toJeType(psiManager)
|
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 (this === other) return true
|
||||||
if (other?.javaClass != javaClass) return false
|
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{
|
override fun hashCode() = psiType.hashCode()
|
||||||
var result = super.hashCode()
|
|
||||||
result = 31 * result + psiType.hashCode()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString() = psiType.getCanonicalText(false)
|
|
||||||
}
|
}
|
||||||
+3
-3
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.java.model.types
|
|||||||
|
|
||||||
import com.intellij.psi.PsiClassInitializer
|
import com.intellij.psi.PsiClassInitializer
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.PsiModifier
|
import org.jetbrains.kotlin.java.model.internal.isStatic
|
||||||
import javax.lang.model.type.*
|
import javax.lang.model.type.*
|
||||||
|
|
||||||
class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitializer) : JeTypeMirror, JeTypeWithManager, ExecutableType {
|
class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitializer) : JeTypeMirror, JeTypeWithManager, ExecutableType {
|
||||||
@@ -29,7 +29,7 @@ class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitialize
|
|||||||
override val psiManager: PsiManager
|
override val psiManager: PsiManager
|
||||||
get() = initializer.manager
|
get() = initializer.manager
|
||||||
|
|
||||||
override fun getReturnType() = CustomJeNoneType(TypeKind.VOID)
|
override fun getReturnType() = JeVoidType
|
||||||
|
|
||||||
override fun getReceiverType() = JeNoneType
|
override fun getReceiverType() = JeNoneType
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitialize
|
|||||||
override fun getTypeVariables() = emptyList<TypeVariable>()
|
override fun getTypeVariables() = emptyList<TypeVariable>()
|
||||||
|
|
||||||
override fun toString() = (initializer.containingClass?.qualifiedName?.let { it + "." } ?: "") +
|
override fun toString() = (initializer.containingClass?.qualifiedName?.let { it + "." } ?: "") +
|
||||||
(if (initializer.hasModifierProperty(PsiModifier.STATIC)) "<clinit>" else "<init>")
|
(if (initializer.isStatic) "<clinit>" else "<instinit>")
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
|
|||||||
+31
-21
@@ -17,45 +17,61 @@
|
|||||||
package org.jetbrains.kotlin.java.model.types
|
package org.jetbrains.kotlin.java.model.types
|
||||||
|
|
||||||
import com.intellij.pom.java.LanguageLevel
|
import com.intellij.pom.java.LanguageLevel
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.PsiClassType
|
|
||||||
import com.intellij.psi.PsiManager
|
|
||||||
import com.intellij.psi.PsiType
|
|
||||||
import com.intellij.psi.impl.light.LightClassReferenceExpression
|
import com.intellij.psi.impl.light.LightClassReferenceExpression
|
||||||
import com.intellij.psi.impl.source.PsiClassReferenceType
|
import com.intellij.psi.impl.source.PsiClassReferenceType
|
||||||
import com.intellij.psi.util.PsiTypesUtil
|
import com.intellij.psi.util.PsiTypesUtil
|
||||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
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.DeclaredType
|
||||||
import javax.lang.model.type.TypeKind
|
import javax.lang.model.type.TypeKind
|
||||||
import javax.lang.model.type.TypeMirror
|
import javax.lang.model.type.TypeMirror
|
||||||
import javax.lang.model.type.TypeVisitor
|
import javax.lang.model.type.TypeVisitor
|
||||||
|
|
||||||
fun createDeclaredType(psiClass: PsiClass, typeArgs: List<PsiType>): PsiClassReferenceType? {
|
fun createDeclaredType(psiClass: PsiClass, typeArgs: List<PsiType>): PsiClassReferenceType? {
|
||||||
val params = typeArgs.toTypedArray()
|
val args = typeArgs.toTypedArray()
|
||||||
val text = (psiClass.name ?: return null) + typeArgs.joinToString(prefix = "<", postfix = ">")
|
val text = (psiClass.name ?: return null) + typeArgs.joinToString(prefix = "<", postfix = ">") { it.canonicalText }
|
||||||
return PsiClassReferenceType(object : LightClassReferenceExpression(psiClass.manager, text, psiClass) {
|
return PsiClassReferenceType(object : LightClassReferenceExpression(psiClass.manager, text, psiClass) {
|
||||||
override fun getTypeParameters() = params
|
override fun getTypeParameters() = args
|
||||||
}, LanguageLevel.JDK_1_8)
|
}, LanguageLevel.JDK_1_8)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JeDeclaredType(
|
class JeDeclaredType(
|
||||||
override val psiType: PsiClassType,
|
override val psiType: PsiClassType,
|
||||||
val psiClass: PsiClass,
|
val psiClass: PsiClass,
|
||||||
val enclosingDeclaredType: DeclaredType? = null,
|
val enclosingDeclaredType: DeclaredType? = null
|
||||||
val typeArgumentMirrors: List<TypeMirror>? = null
|
|
||||||
) : JePsiType(), JeTypeWithManager, DeclaredType {
|
) : JePsiType(), JeTypeWithManager, DeclaredType {
|
||||||
override fun getKind() = TypeKind.DECLARED
|
override fun getKind() = TypeKind.DECLARED
|
||||||
|
|
||||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitDeclared(this, p)
|
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitDeclared(this, p)
|
||||||
|
|
||||||
override val psiManager: PsiManager
|
override val psiManager: PsiManager
|
||||||
get() = psiClass.manager
|
get() = psiClass.manager
|
||||||
|
|
||||||
override fun getTypeArguments() = typeArgumentMirrors ?: psiType.parameters.map { it.toJeType(psiManager) }
|
override fun getTypeArguments(): List<TypeMirror> {
|
||||||
|
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 asElement() = JeTypeElement(psiClass)
|
||||||
|
|
||||||
override fun getEnclosingType(): TypeMirror {
|
override fun getEnclosingType(): TypeMirror {
|
||||||
|
if (!psiClass.isStatic) return JeNoneType
|
||||||
|
|
||||||
if (enclosingDeclaredType != null) return enclosingDeclaredType
|
if (enclosingDeclaredType != null) return enclosingDeclaredType
|
||||||
|
|
||||||
val psiClass = psiClass.containingClass ?: return JeNoneType
|
val psiClass = psiClass.containingClass ?: return JeNoneType
|
||||||
return PsiTypesUtil.getClassType(psiClass).toJeType(psiManager)
|
return PsiTypesUtil.getClassType(psiClass).toJeType(psiManager)
|
||||||
}
|
}
|
||||||
@@ -63,16 +79,10 @@ class JeDeclaredType(
|
|||||||
override fun equals(other: Any?): Boolean{
|
override fun equals(other: Any?): Boolean{
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other?.javaClass != javaClass) return false
|
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 {
|
override fun hashCode() = psiType.hashCode()
|
||||||
var result = super.hashCode()
|
|
||||||
result = 31 * result + psiType.hashCode()
|
override fun toString() = psiType.getCanonicalText(false)
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String = psiType.getCanonicalText(false)
|
|
||||||
}
|
}
|
||||||
+9
@@ -28,5 +28,14 @@ class JeIntersectionType(
|
|||||||
) : JePsiType(), JeTypeWithManager, IntersectionType {
|
) : JePsiType(), JeTypeWithManager, IntersectionType {
|
||||||
override fun getKind() = TypeKind.INTERSECTION
|
override fun getKind() = TypeKind.INTERSECTION
|
||||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitIntersection(this, p)
|
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitIntersection(this, p)
|
||||||
|
|
||||||
override fun getBounds() = psiType.superTypes.map { it.toJeType(psiManager) }
|
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()
|
||||||
}
|
}
|
||||||
+1
-1
@@ -36,7 +36,7 @@ class JeMethodExecutableTypeMirror(
|
|||||||
|
|
||||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, 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()
|
override fun getReceiverType() = psi.getReceiverTypeMirror()
|
||||||
|
|
||||||
|
|||||||
+3
-9
@@ -40,17 +40,11 @@ class JePrimitiveType(override val psiType: PsiPrimitiveType) : JePsiType(), Pri
|
|||||||
|
|
||||||
override fun toString() = psiType.canonicalText
|
override fun toString() = psiType.canonicalText
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean{
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other?.javaClass != javaClass) return false
|
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{
|
override fun hashCode() = psiType.hashCode()
|
||||||
var result = super.hashCode()
|
|
||||||
result = 31 * result + psiType.hashCode()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -20,22 +20,4 @@ import com.intellij.psi.PsiType
|
|||||||
|
|
||||||
abstract class JePsiType : JeTypeMirror {
|
abstract class JePsiType : JeTypeMirror {
|
||||||
abstract val psiType: PsiType
|
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+11
-2
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.java.model.types
|
package org.jetbrains.kotlin.java.model.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.java.model.JeConverter
|
|
||||||
import org.jetbrains.kotlin.java.model.elements.JeTypeParameterElement
|
import org.jetbrains.kotlin.java.model.elements.JeTypeParameterElement
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.kotlin.java.model.toJeElement
|
||||||
import javax.lang.model.type.TypeKind
|
import javax.lang.model.type.TypeKind
|
||||||
import javax.lang.model.type.TypeMirror
|
import javax.lang.model.type.TypeMirror
|
||||||
import javax.lang.model.type.TypeVariable
|
import javax.lang.model.type.TypeVariable
|
||||||
@@ -29,6 +29,7 @@ class JeTypeVariableType(
|
|||||||
val parameter: PsiTypeParameter
|
val parameter: PsiTypeParameter
|
||||||
) : JePsiType(), JeTypeWithManager, TypeVariable {
|
) : JePsiType(), JeTypeWithManager, TypeVariable {
|
||||||
override fun getKind() = TypeKind.TYPEVAR
|
override fun getKind() = TypeKind.TYPEVAR
|
||||||
|
|
||||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitTypeVariable(this, p)
|
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitTypeVariable(this, p)
|
||||||
|
|
||||||
override val psiManager: PsiManager
|
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()
|
||||||
}
|
}
|
||||||
+22
-8
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.java.model.types
|
package org.jetbrains.kotlin.java.model.types
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiCapturedWildcardType
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.PsiWildcardType
|
import com.intellij.psi.PsiWildcardType
|
||||||
import javax.lang.model.type.TypeKind
|
import javax.lang.model.type.TypeKind
|
||||||
@@ -32,17 +33,30 @@ class JeWildcardType(override val psiType: PsiWildcardType) : JePsiType(), JeTyp
|
|||||||
override val psiManager: PsiManager
|
override val psiManager: PsiManager
|
||||||
get() = psiType.manager
|
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 <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, 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 {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other?.javaClass != javaClass) return false
|
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 {
|
override fun hashCode() = psiType.hashCode()
|
||||||
var result = super.hashCode()
|
|
||||||
result = 31 * result + psiType.hashCode()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,8 @@ import java.lang.reflect.Array as RArray
|
|||||||
private val PSI_PRIMITIVES_MAP = listOf(
|
private val PSI_PRIMITIVES_MAP = listOf(
|
||||||
PsiType.BYTE, PsiType.CHAR, PsiType.DOUBLE,
|
PsiType.BYTE, PsiType.CHAR, PsiType.DOUBLE,
|
||||||
PsiType.FLOAT, PsiType.INT, PsiType.LONG,
|
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(
|
private val TYPE_KIND_TO_PSI_PRIMITIVE_MAP = mapOf(
|
||||||
TypeKind.BYTE to PsiType.BYTE,
|
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 PsiPrimitiveType -> PSI_PRIMITIVES_MAP[this] ?: JeErrorType
|
||||||
is PsiArrayType -> JeArrayType(this, manager)
|
is PsiArrayType -> JeArrayType(this, manager)
|
||||||
is PsiWildcardType -> JeWildcardType(this)
|
is PsiWildcardType -> JeWildcardType(this)
|
||||||
|
is PsiCapturedWildcardType -> JeCapturedWildcardType(this, manager)
|
||||||
is PsiClassType -> {
|
is PsiClassType -> {
|
||||||
val resolvedClass = this.resolve()
|
val resolvedClass = this.resolve()
|
||||||
when (resolvedClass) {
|
when (resolvedClass) {
|
||||||
|
|||||||
Reference in New Issue
Block a user