From 77819be8f358bdde9f63043c0c8e222b5b90a4d6 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 13 Nov 2018 18:08:13 +0300 Subject: [PATCH] New J2K: Add function to lookup symbols by fqName --- .../jetbrains/kotlin/j2k/JKSymbolProvider.kt | 26 ++++++++++-- .../jetbrains/kotlin/j2k/tree/impl/symbols.kt | 42 +++++++++++++------ 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt index 9821544a7eb..620f6e442df 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt @@ -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() val symbolsByJK = mutableMapOf() + private val elementVisitor = ElementVisitor() fun preBuildTree(files: List) { @@ -34,10 +41,10 @@ class JKSymbolProvider { } } - inline fun provideSymbol(reference: PsiReference): T { + internal inline fun 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()) 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 provideByFqName(classId: ClassId, context: PsiElement = symbolsByPsi.keys.first()): T { + return resolveFqName(classId, context)?.let(::provideDirectSymbol).safeAs() ?: when { + isAssignable() -> JKUnresolvedMethod(classId.asSingleFqName().asString().replace('/', '.')) + isAssignable() -> JKUnresolvedField(classId.asSingleFqName().asString().replace('/', '.')) + else -> JKUnresolvedClassSymbol(classId.asSingleFqName().asString().replace('/', '.')) + } as T + } + + internal inline fun 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 isAssignable(): Boolean = A::class.java.isAssignableFrom(B::class.java) } \ No newline at end of file diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt index 42383149e58..0bf8b19942a 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/impl/symbols.kt @@ -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 : 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 { @@ -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('.') }