New J2K: Fix provideDirectSymbol in symbol provider fro decompiled declaratiosns

This commit is contained in:
Ilya Kirillov
2019-02-13 13:19:14 +03:00
committed by Ilya Kirillov
parent 0456c6a897
commit 67a8f445b0
2 changed files with 50 additions and 22 deletions
@@ -6,15 +6,17 @@
package org.jetbrains.kotlin.nj2k
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
import org.jetbrains.kotlin.nj2k.conversions.multiResolveFqName
import org.jetbrains.kotlin.nj2k.conversions.resolveFqName
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.nj2k.conversions.multiResolveFqName
import org.jetbrains.kotlin.nj2k.conversions.resolveFqName
import org.jetbrains.kotlin.nj2k.tree.JKClass
import org.jetbrains.kotlin.nj2k.tree.JKDeclaration
import org.jetbrains.kotlin.nj2k.tree.JKMethod
import org.jetbrains.kotlin.nj2k.tree.JKVariable
import org.jetbrains.kotlin.nj2k.tree.impl.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -30,28 +32,38 @@ class JKSymbolProvider {
files.forEach { it.accept(elementVisitor) }
}
private fun symbolForNonKotlinElement(psi: PsiElement) =
when (psi) {
is KtEnumEntry -> JKMultiverseKtEnumEntrySymbol(psi, this)
is PsiClass -> JKMultiverseClassSymbol(psi, this)
is KtClassOrObject -> JKMultiverseKtClassSymbol(psi, this)
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
is PsiField -> JKMultiverseFieldSymbol(psi, this)
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi, this)
is KtProperty -> JKMultiversePropertySymbol(psi, this)
is KtParameter -> JKMultiversePropertySymbol(psi, this)
is PsiParameter -> JKMultiverseFieldSymbol(psi, this)
is PsiLocalVariable -> JKMultiverseFieldSymbol(psi, this)
else -> TODO(psi::class.toString())
}
fun provideDirectSymbol(psi: PsiElement): JKSymbol {
return symbolsByPsi.getOrPut(psi) {
when (psi) {
is KtLightDeclaration<*, *> -> provideDirectSymbol(psi.kotlinOrigin!!)
is PsiClass -> JKMultiverseClassSymbol(psi)
is KtClassOrObject -> JKMultiverseKtClassSymbol(psi)
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
is PsiField -> JKMultiverseFieldSymbol(psi, this)
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi, this)
is KtProperty -> JKMultiversePropertySymbol(psi, this)
is KtParameter -> JKMultiversePropertySymbol(psi, this)
is PsiParameter -> JKMultiverseFieldSymbol(psi, this)
is PsiLocalVariable -> JKMultiverseFieldSymbol(psi, this)
else -> TODO(psi::class.toString())
}
if (psi is KtLightDeclaration<*, *>)
psi.kotlinOrigin
?.let { provideDirectSymbol(it) }
?: symbolForNonKotlinElement(psi)
else symbolForNonKotlinElement(psi)
}
}
internal inline fun <reified T : JKSymbol> provideSymbol(reference: PsiReference): T {
val target = reference.resolve()
if (target != null) return provideDirectSymbol(target) as T
return (if (isAssignable<T, JKUnresolvedField>()) JKUnresolvedField(reference.canonicalText, this) else JKUnresolvedMethod(reference)) as T
return (if (isAssignable<T, JKUnresolvedField>()) JKUnresolvedField(
reference.canonicalText,
this
) else JKUnresolvedMethod(reference)) as T
}
fun provideUniverseSymbol(psi: PsiElement, jk: JKDeclaration): JKSymbol = provideUniverseSymbol(psi).also {
@@ -301,7 +301,9 @@ class JavaToJKTreeBuilder(
fun PsiReferenceExpression.toJK(): JKExpression {
val target = resolve()
if (target is KtLightClassForFacade) return JKStubExpressionImpl()
if (target is KtLightClassForFacade
|| target is KtLightClassForDecompiledDeclaration
) return JKStubExpressionImpl()
if (target is KtLightField
&& target.name == "INSTANCE"
&& target.containingClass.kotlinOrigin is KtObjectDeclaration
@@ -388,8 +390,22 @@ class JavaToJKTreeBuilder(
return JKParenthesizedExpressionImpl(expression?.toJK() ?: TODO())
}
fun PsiExpressionList?.toJK(): JKExpressionList {
return JKExpressionListImpl(this?.expressions?.map { it.toJK() } ?: emptyList())
fun PsiExpressionList.toJK(): JKArgumentList {
val jkExpressions = expressions.map { it.toJK() }
return ((parent as? PsiCall)?.resolveMethod()
?.let { method ->
if (jkExpressions.size == method.parameterList.parameters.size
&& method.parameterList.parameters.getOrNull(jkExpressions.lastIndex)?.isVarArgs == true
&& expressions.lastOrNull()?.type is PsiArrayType
) {
val staredExpression =
JKPrefixExpressionImpl(
jkExpressions.last(),
JKKtSpreadOperator
)
jkExpressions.dropLast(1) + staredExpression
} else jkExpressions
} ?: jkExpressions).let { it.toArgumentList() }
}
}