diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt index ace2b9a1ffa..f70a6ae8f47 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt @@ -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 provideSymbol(reference: PsiReference): T { val target = reference.resolve() if (target != null) return provideDirectSymbol(target) as T - return (if (isAssignable()) JKUnresolvedField(reference.canonicalText, this) else JKUnresolvedMethod(reference)) as T + return (if (isAssignable()) JKUnresolvedField( + reference.canonicalText, + this + ) else JKUnresolvedMethod(reference)) as T } fun provideUniverseSymbol(psi: PsiElement, jk: JKDeclaration): JKSymbol = provideUniverseSymbol(psi).also { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt index 50bd18be534..15004456da8 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt @@ -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() } } }