diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt index a4a0f0229a4..a7ec7fe1b26 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/NewJ2kPostProcessings.kt @@ -94,6 +94,7 @@ object NewJ2KPostProcessingRegistrarImpl : J2KPostProcessingRegistrar { SingleProcessing(RemoveExplicitTypeArgumentsProcessing()), SingleProcessing(RemoveRedundantOverrideVisibilityProcessing()), registerInspectionBasedProcessing(MoveLambdaOutsideParenthesesInspection()), + registerGeneralInspectionBasedProcessing(RedundantCompanionReferenceInspection()), SingleProcessing(FixObjectStringConcatenationProcessing()), SingleProcessing(ConvertToStringTemplateProcessing()), SingleProcessing(UsePropertyAccessSyntaxProcessing()), diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt index fe6916de1ef..bdf76140b5c 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JKSymbolProvider.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.j2k import com.intellij.psi.* +import org.jetbrains.kotlin.asJava.classes.KtLightClass +import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration import org.jetbrains.kotlin.j2k.conversions.multiResolveFqName import org.jetbrains.kotlin.j2k.conversions.resolveFqName import org.jetbrains.kotlin.j2k.tree.* @@ -30,6 +32,7 @@ class JKSymbolProvider { 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) diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt index 4b045ab6a0b..438b5c5b30c 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt @@ -27,6 +27,7 @@ import com.intellij.psi.tree.IElementType import com.intellij.psi.util.InheritanceUtil import com.intellij.psi.util.PsiUtil import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade +import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.idea.j2k.content import org.jetbrains.kotlin.j2k.ast.Nullability @@ -202,17 +203,19 @@ class JavaToJKTreeBuilder( } private fun JKExpression.qualified(qualifier: JKExpression?) = - if (qualifier != null) { + if (qualifier != null && qualifier !is JKStubExpression) { JKQualifiedExpressionImpl(qualifier, JKJavaQualifierImpl.DOT, this) } else this //TODO mostly copied from old j2k, refactor fun PsiMethodCallExpression.toJK(): JKExpression { - val arguments = argumentList.toJK() + val arguments = argumentList val typeArguments = typeArgumentList.toJK() val qualifier = methodExpression.qualifierExpression?.toJK() val target = methodExpression.resolve() - val symbol = symbolProvider.provideSymbol(methodExpression as PsiReferenceExpressionImpl) + val symbol = target?.let { + symbolProvider.provideDirectSymbol(it) + } ?: JKUnresolvedMethod(methodExpression) return when { methodExpression.referenceNameElement is PsiKeyword -> { @@ -221,7 +224,7 @@ class JavaToJKTreeBuilder( THIS_KEYWORD -> JKThisExpressionImpl(JKLabelEmptyImpl()) else -> error("Unknown keyword in callee position") } - JKDelegationConstructorCallImpl(symbol, callee, arguments) + JKDelegationConstructorCallImpl(symbol as JKMethodSymbol, callee, arguments.toJK()) } target is KtLightMethod -> { @@ -229,16 +232,16 @@ class JavaToJKTreeBuilder( when (origin) { is KtNamedFunction -> { if (origin.isExtensionDeclaration()) { - val receiver = arguments.expressions.firstOrNull() + val receiver = arguments.expressions.firstOrNull()?.toJK()?.parenthesizeIfBinaryExpression() JKJavaMethodCallExpressionImpl( symbolProvider.provideDirectSymbol(origin) as JKMethodSymbol, - arguments.also { it.expressions = it.expressions.drop(1) }, + arguments.expressions.drop(1).map { it.toJK() }.toExpressionList(), typeArguments ).qualified(receiver) } else { JKJavaMethodCallExpressionImpl( symbolProvider.provideDirectSymbol(origin) as JKMethodSymbol, - arguments, + arguments.expressions.map { it.toJK() }.toExpressionList(), typeArguments ).qualified(qualifier) } @@ -254,7 +257,7 @@ class JavaToJKTreeBuilder( val isTopLevel = origin.getStrictParentOfType() == null val propertyAccess = if (isTopLevel) { if (isExtension) JKQualifiedExpressionImpl( - arguments.expressions.first().detached(arguments), + arguments.expressions.first().toJK(), JKJavaQualifierImpl.DOT, propertyAccessExpression ) @@ -266,7 +269,7 @@ class JavaToJKTreeBuilder( propertyAccess 1 /* setter */ -> { - val argument = (arguments.expressions[if (isExtension) 1 else 0]).detached(arguments) + val argument = (arguments.expressions[if (isExtension) 1 else 0]).toJK() JKJavaAssignmentExpressionImpl( propertyAccess, argument, @@ -281,23 +284,31 @@ class JavaToJKTreeBuilder( } } - target is PsiMethod -> - JKJavaMethodCallExpressionImpl(symbol, arguments, typeArguments) - .qualified(qualifier) - else -> - JKJavaMethodCallExpressionImpl(symbol, arguments, typeArguments) + symbol is JKMethodSymbol -> + JKJavaMethodCallExpressionImpl(symbol, arguments.toJK(), typeArguments) .qualified(qualifier) + symbol is JKFieldSymbol -> + JKFieldAccessExpressionImpl(symbol).qualified(qualifier) + else -> TODO(text) } } fun PsiReferenceExpression.toJK(): JKExpression { + val target = resolve() + if (target is KtLightClassForFacade) return JKStubExpressionImpl() + if (target is KtLightField + && target.name == "INSTANCE" + && target.containingClass.kotlinOrigin is KtObjectDeclaration + ) { + return qualifierExpression?.toJK() ?: JKStubExpressionImpl() + } + val symbol = symbolProvider.provideSymbol(this) - val access = when (symbol) { + return when (symbol) { is JKClassSymbol -> JKClassAccessExpressionImpl(symbol) is JKFieldSymbol -> JKFieldAccessExpressionImpl(symbol) else -> TODO() - } - return qualifierExpression?.let { JKQualifiedExpressionImpl(it.toJK(), JKJavaQualifierImpl.DOT, access) } ?: access + }.qualified(qualifierExpression?.toJK()) } fun PsiArrayInitializerExpression.toJK(): JKExpression { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/expressions.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/expressions.kt index c9902a52484..398505df778 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/expressions.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/expressions.kt @@ -221,6 +221,15 @@ fun downToExpression( psiContext ) +fun List.toExpressionList() = + JKExpressionListImpl(this) + +fun JKExpression.parenthesizeIfBinaryExpression() = + when (this) { + is JKBinaryExpression -> JKParenthesizedExpressionImpl(this) + else -> this + } + fun rangeExpression( from: JKExpression, to: JKExpression, @@ -237,6 +246,9 @@ fun rangeExpression( fun blockStatement(vararg statements: JKStatement) = JKBlockStatementImpl(JKBlockImpl(statements.toList())) +fun blockStatement(statements: List) = + JKBlockStatementImpl(JKBlockImpl(statements)) + fun useExpression( receiver: JKExpression, variableIdentifier: JKNameIdentifier,