New J2K: Add function to lookup symbols by fqName
This commit is contained in:
committed by
Ilya Kirillov
parent
c43bfcb185
commit
77819be8f3
@@ -6,15 +6,22 @@
|
||||
package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.conversions.resolveFqName
|
||||
import org.jetbrains.kotlin.j2k.tree.JKClass
|
||||
import org.jetbrains.kotlin.j2k.tree.JKDeclaration
|
||||
import org.jetbrains.kotlin.j2k.tree.JKField
|
||||
import org.jetbrains.kotlin.j2k.tree.JKMethod
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
class JKSymbolProvider {
|
||||
val symbolsByPsi = mutableMapOf<PsiElement, JKSymbol>()
|
||||
val symbolsByJK = mutableMapOf<JKDeclaration, JKSymbol>()
|
||||
|
||||
private val elementVisitor = ElementVisitor()
|
||||
|
||||
fun preBuildTree(files: List<PsiJavaFile>) {
|
||||
@@ -34,10 +41,10 @@ class JKSymbolProvider {
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T : JKSymbol> provideSymbol(reference: PsiReference): T {
|
||||
internal inline fun <reified T : JKSymbol> provideSymbol(reference: PsiReference): T {
|
||||
val target = reference.resolve()
|
||||
if (target != null) return provideDirectSymbol(target) as T
|
||||
return JKUnresolvedField(reference).let { if (it is T) it else JKUnresolvedMethod(reference) as T }
|
||||
return (if (isAssignable<T, JKUnresolvedField>()) JKUnresolvedField(reference) else JKUnresolvedMethod(reference)) as T
|
||||
}
|
||||
|
||||
fun provideUniverseSymbol(psi: PsiElement, jk: JKDeclaration): JKSymbol = provideUniverseSymbol(psi).also {
|
||||
@@ -76,6 +83,17 @@ class JKSymbolProvider {
|
||||
JKUniverseMethodSymbol(this).also { it.target = jk }
|
||||
} as JKMethodSymbol
|
||||
|
||||
internal inline fun <reified T : JKSymbol> provideByFqName(classId: ClassId, context: PsiElement = symbolsByPsi.keys.first()): T {
|
||||
return resolveFqName(classId, context)?.let(::provideDirectSymbol).safeAs<T>() ?: when {
|
||||
isAssignable<T, JKUnresolvedMethod>() -> JKUnresolvedMethod(classId.asSingleFqName().asString().replace('/', '.'))
|
||||
isAssignable<T, JKUnresolvedField>() -> JKUnresolvedField(classId.asSingleFqName().asString().replace('/', '.'))
|
||||
else -> JKUnresolvedClassSymbol(classId.asSingleFqName().asString().replace('/', '.'))
|
||||
} as T
|
||||
}
|
||||
|
||||
internal inline fun <reified T : JKSymbol> provideByFqName(fqName: String, context: PsiElement = symbolsByPsi.keys.first()): T =
|
||||
provideByFqName(ClassId.fromString(fqName), context)
|
||||
|
||||
private inner class ElementVisitor : JavaElementVisitor() {
|
||||
override fun visitClass(aClass: PsiClass) {
|
||||
provideUniverseSymbol(aClass)
|
||||
@@ -94,4 +112,6 @@ class JKSymbolProvider {
|
||||
file.acceptChildren(this)
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified A, reified B> isAssignable(): Boolean = A::class.java.isAssignableFrom(B::class.java)
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
interface JKSymbol {
|
||||
val target: Any
|
||||
val declaredIn: JKSymbol?
|
||||
val fqName: String?
|
||||
}
|
||||
|
||||
interface JKNamedSymbol : JKSymbol {
|
||||
@@ -31,16 +32,14 @@ interface JKUniverseSymbol<T: JKTreeElement> : JKSymbol {
|
||||
override var target: T
|
||||
}
|
||||
|
||||
interface JKClassSymbol : JKNamedSymbol {
|
||||
val fqName: String?
|
||||
}
|
||||
interface JKClassSymbol : JKNamedSymbol
|
||||
|
||||
interface JKMethodSymbol : JKNamedSymbol {
|
||||
val fqName: String
|
||||
override val fqName: String
|
||||
}
|
||||
|
||||
interface JKFieldSymbol : JKNamedSymbol {
|
||||
val fqName: String
|
||||
override val fqName: String
|
||||
}
|
||||
|
||||
class JKUniverseClassSymbol : JKClassSymbol, JKUniverseSymbol<JKClass> {
|
||||
@@ -121,18 +120,35 @@ class JKMultiverseFieldSymbol(override val target: PsiField) : JKFieldSymbol {
|
||||
get() = target.name // TODO("Fix this")
|
||||
}
|
||||
|
||||
class JKUnresolvedField(override val target: PsiReference) : JKFieldSymbol {
|
||||
override val name: String
|
||||
get() = TODO("not implemented")
|
||||
class JKUnresolvedField(override val target: String) : JKFieldSymbol {
|
||||
constructor(target: PsiReference) : this(target.canonicalText)
|
||||
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val fqName: String = target.canonicalText
|
||||
override val fqName: String = target
|
||||
|
||||
override val name: String
|
||||
get() = target
|
||||
}
|
||||
|
||||
class JKUnresolvedMethod(override val target: PsiReference) : JKMethodSymbol {
|
||||
override val name: String
|
||||
get() = TODO("not implemented")
|
||||
class JKUnresolvedMethod(override val target: String) : JKMethodSymbol {
|
||||
constructor(target: PsiReference) : this(target.canonicalText)
|
||||
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val fqName: String = target.canonicalText
|
||||
override val fqName: String = target
|
||||
|
||||
override val name: String
|
||||
get() = target
|
||||
}
|
||||
|
||||
class JKUnresolvedClassSymbol(override val target: String) : JKClassSymbol {
|
||||
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val fqName: String?
|
||||
get() = target
|
||||
|
||||
override val name: String
|
||||
get() = target.substringAfterLast('.')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user