New J2K: always print real fqNames for static calls
As fqNames of some symbols may change during conversion E.g, when moving Java static method to Kotlin companion object #KT-19607 fixed #KT-32903 fixed #KT-33743 fixed #KT-33556 fixed
This commit is contained in:
@@ -17,10 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.conversions.*
|
import org.jetbrains.kotlin.nj2k.conversions.*
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.JKLambdaExpression
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.JKParameter
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKTreeRoot
|
import org.jetbrains.kotlin.nj2k.tree.JKTreeRoot
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
object ConversionsRunner {
|
object ConversionsRunner {
|
||||||
|
|
||||||
private fun createConversions(context: NewJ2kConverterContext) = listOf(
|
private fun createConversions(context: NewJ2kConverterContext) = listOf(
|
||||||
NonCodeElementsConversion(context),
|
NonCodeElementsConversion(context),
|
||||||
JavaModifiersConversion(context),
|
JavaModifiersConversion(context),
|
||||||
@@ -38,7 +40,6 @@ object ConversionsRunner {
|
|||||||
ArrayInitializerConversion(context),
|
ArrayInitializerConversion(context),
|
||||||
TryStatementConversion(context),
|
TryStatementConversion(context),
|
||||||
EnumFieldAccessConversion(context),
|
EnumFieldAccessConversion(context),
|
||||||
StaticMemberAccessConversion(context),
|
|
||||||
SynchronizedStatementConversion(context),
|
SynchronizedStatementConversion(context),
|
||||||
JetbrainsNullableAnnotationsConverter(context),
|
JetbrainsNullableAnnotationsConverter(context),
|
||||||
DefaultArgumentsConversion(context),
|
DefaultArgumentsConversion(context),
|
||||||
@@ -69,9 +70,14 @@ object ConversionsRunner {
|
|||||||
ClassToObjectPromotionConversion(context),
|
ClassToObjectPromotionConversion(context),
|
||||||
RemoveWrongExtraModifiersForSingleFunctionsConversion(context),
|
RemoveWrongExtraModifiersForSingleFunctionsConversion(context),
|
||||||
MethodReferenceToLambdaConversion(context),
|
MethodReferenceToLambdaConversion(context),
|
||||||
|
TypeMappingConversion(context) { typeElement ->
|
||||||
|
typeElement.parent.safeAs<JKParameter>()?.parent is JKLambdaExpression
|
||||||
|
},
|
||||||
BuiltinMembersConversion(context),
|
BuiltinMembersConversion(context),
|
||||||
ImplicitCastsConversion(context),
|
ImplicitCastsConversion(context),
|
||||||
LiteralConversion(context),
|
LiteralConversion(context),
|
||||||
|
StaticMemberAccessConversion(context),
|
||||||
|
RemoveRedundantQualifiersForCallsConversion(context),
|
||||||
FilterImportsConversion(context),
|
FilterImportsConversion(context),
|
||||||
MoveInitBlocksToTheEndConversion(context),
|
MoveInitBlocksToTheEndConversion(context),
|
||||||
AddElementsInfoConversion(context)
|
AddElementsInfoConversion(context)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElement) {
|
class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElement) {
|
||||||
private val symbolsByFqName = mutableMapOf<String, JKSymbol>()
|
private val symbolsByFqName = mutableMapOf<String, JKSymbol>()
|
||||||
val symbolsByPsi = mutableMapOf<PsiElement, JKSymbol>()
|
val symbolsByPsi = mutableMapOf<PsiElement, JKSymbol>()
|
||||||
val symbolsByJK = mutableMapOf<JKDeclaration, JKSymbol>()
|
private val symbolsByJK = mutableMapOf<JKDeclaration, JKSymbol>()
|
||||||
private val resolver = JKResolver(project, module, contextElement)
|
private val resolver = JKResolver(project, module, contextElement)
|
||||||
|
|
||||||
private val elementVisitor = ElementVisitor()
|
private val elementVisitor = ElementVisitor()
|
||||||
@@ -68,14 +68,15 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
|||||||
) else JKUnresolvedMethod(reference, typeFactory)) as T
|
) else JKUnresolvedMethod(reference, typeFactory)) as T
|
||||||
}
|
}
|
||||||
|
|
||||||
fun provideUniverseSymbol(psi: PsiElement, jk: JKDeclaration): JKSymbol = provideUniverseSymbol(psi).also {
|
fun provideUniverseSymbol(psi: PsiElement, declaration: JKDeclaration): JKSymbol = provideUniverseSymbol(psi).also { symbol ->
|
||||||
when (it) {
|
when (symbol) {
|
||||||
is JKUniverseClassSymbol -> it.target = jk as JKClass
|
is JKUniverseClassSymbol -> symbol.target = declaration as JKClass
|
||||||
is JKUniverseFieldSymbol -> it.target = jk as JKVariable
|
is JKUniverseFieldSymbol -> symbol.target = declaration as JKVariable
|
||||||
is JKUniverseMethodSymbol -> it.target = jk as JKMethod
|
is JKUniverseMethodSymbol -> symbol.target = declaration as JKMethod
|
||||||
is JKUniverseTypeParameterSymbol -> it.target = jk as JKTypeParameter
|
is JKUniverseTypeParameterSymbol -> symbol.target = declaration as JKTypeParameter
|
||||||
|
is JKUniversePackageSymbol -> symbol.target = declaration as JKPackageDeclaration
|
||||||
}
|
}
|
||||||
symbolsByJK[jk] = it
|
symbolsByJK[declaration] = symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
fun provideUniverseSymbol(psi: PsiElement): JKSymbol =
|
fun provideUniverseSymbol(psi: PsiElement): JKSymbol =
|
||||||
@@ -85,6 +86,7 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
|||||||
is PsiMethod -> JKUniverseMethodSymbol(typeFactory)
|
is PsiMethod -> JKUniverseMethodSymbol(typeFactory)
|
||||||
is PsiTypeParameter -> JKUniverseTypeParameterSymbol(typeFactory)
|
is PsiTypeParameter -> JKUniverseTypeParameterSymbol(typeFactory)
|
||||||
is PsiClass -> JKUniverseClassSymbol(typeFactory)
|
is PsiClass -> JKUniverseClassSymbol(typeFactory)
|
||||||
|
is PsiPackageStatement -> JKUniversePackageSymbol(typeFactory)
|
||||||
else -> TODO()
|
else -> TODO()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,6 +110,22 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
|||||||
JKUniverseMethodSymbol(typeFactory).also { it.target = jk }
|
JKUniverseMethodSymbol(typeFactory).also { it.target = jk }
|
||||||
} as JKMethodSymbol
|
} as JKMethodSymbol
|
||||||
|
|
||||||
|
fun provideUniverseSymbol(jk: JKTypeParameter): JKTypeParameterSymbol = symbolsByJK.getOrPut(jk) {
|
||||||
|
JKUniverseTypeParameterSymbol(typeFactory).also { it.target = jk }
|
||||||
|
} as JKTypeParameterSymbol
|
||||||
|
|
||||||
|
fun provideUniverseSymbol(jk: JKPackageDeclaration): JKPackageSymbol = symbolsByJK.getOrPut(jk) {
|
||||||
|
JKUniversePackageSymbol(typeFactory).also { it.target = jk }
|
||||||
|
} as JKPackageSymbol
|
||||||
|
|
||||||
|
fun provideUniverseSymbol(jk: JKDeclaration): JKUniverseSymbol<*>? = when (jk) {
|
||||||
|
is JKClass -> provideUniverseSymbol(jk)
|
||||||
|
is JKVariable -> provideUniverseSymbol(jk)
|
||||||
|
is JKMethod -> provideUniverseSymbol(jk)
|
||||||
|
is JKTypeParameter -> provideUniverseSymbol(jk)
|
||||||
|
else -> null
|
||||||
|
} as? JKUniverseSymbol<*>
|
||||||
|
|
||||||
|
|
||||||
fun provideClassSymbol(fqName: FqName): JKClassSymbol =
|
fun provideClassSymbol(fqName: FqName): JKClassSymbol =
|
||||||
symbolsByFqName.getOrPutIfNotNull(fqName.asString()) {
|
symbolsByFqName.getOrPutIfNotNull(fqName.asString()) {
|
||||||
@@ -175,6 +193,10 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
|||||||
provideUniverseSymbol(classParameter)
|
provideUniverseSymbol(classParameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitPackageStatement(statement: PsiPackageStatement) {
|
||||||
|
provideUniverseSymbol(statement)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitFile(file: PsiFile) {
|
override fun visitFile(file: PsiFile) {
|
||||||
file.acceptChildren(this)
|
file.acceptChildren(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.nj2k.symbols.*
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.getDisplayName
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitorWithCommentsPrinting
|
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitorWithCommentsPrinting
|
||||||
import org.jetbrains.kotlin.nj2k.types.*
|
import org.jetbrains.kotlin.nj2k.types.*
|
||||||
@@ -160,7 +158,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClassAccessExpressionRaw(classAccessExpression: JKClassAccessExpression) {
|
override fun visitClassAccessExpressionRaw(classAccessExpression: JKClassAccessExpression) {
|
||||||
printer.renderClassSymbol(classAccessExpression.identifier, classAccessExpression)
|
printer.renderSymbol(classAccessExpression.identifier, classAccessExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFileRaw(file: JKFile) {
|
override fun visitFileRaw(file: JKFile) {
|
||||||
@@ -522,7 +520,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCallExpressionRaw(callExpression: JKCallExpression) {
|
override fun visitCallExpressionRaw(callExpression: JKCallExpression) {
|
||||||
printer.printWithNoIndent(FqName(callExpression.identifier.fqName).shortName().asString().escaped())
|
printer.renderSymbol(callExpression.identifier, callExpression)
|
||||||
callExpression.typeArgumentList.accept(this)
|
callExpression.typeArgumentList.accept(this)
|
||||||
printer.par {
|
printer.par {
|
||||||
callExpression.arguments.accept(this)
|
callExpression.arguments.accept(this)
|
||||||
@@ -603,7 +601,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
if (newExpression.isAnonymousClass) {
|
if (newExpression.isAnonymousClass) {
|
||||||
printer.printWithNoIndent("object : ")
|
printer.printWithNoIndent("object : ")
|
||||||
}
|
}
|
||||||
printer.renderClassSymbol(newExpression.classSymbol, newExpression)
|
printer.renderSymbol(newExpression.classSymbol, newExpression)
|
||||||
newExpression.typeArgumentList.accept(this)
|
newExpression.typeArgumentList.accept(this)
|
||||||
if (!newExpression.classSymbol.isInterface() || newExpression.arguments.arguments.isNotEmpty()) {
|
if (!newExpression.classSymbol.isInterface() || newExpression.arguments.arguments.isNotEmpty()) {
|
||||||
printer.par(ParenthesisKind.ROUND) {
|
printer.par(ParenthesisKind.ROUND) {
|
||||||
@@ -667,11 +665,11 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFieldAccessExpressionRaw(fieldAccessExpression: JKFieldAccessExpression) {
|
override fun visitFieldAccessExpressionRaw(fieldAccessExpression: JKFieldAccessExpression) {
|
||||||
printer.printWithNoIndent(fieldAccessExpression.identifier.name.escaped())
|
printer.renderSymbol(fieldAccessExpression.identifier, fieldAccessExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPackageAccessExpressionRaw(packageAccessExpression: JKPackageAccessExpression) {
|
override fun visitPackageAccessExpressionRaw(packageAccessExpression: JKPackageAccessExpression) {
|
||||||
printer.printWithNoIndent(packageAccessExpression.identifier.name.escaped())
|
printer.renderSymbol(packageAccessExpression.identifier, packageAccessExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitMethodReferenceExpressionRaw(methodReferenceExpression: JKMethodReferenceExpression) {
|
override fun visitMethodReferenceExpressionRaw(methodReferenceExpression: JKMethodReferenceExpression) {
|
||||||
@@ -896,8 +894,10 @@ private class JKPrinter(
|
|||||||
printWithNoIndent(kind.close)
|
printWithNoIndent(kind.close)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKClassSymbol.needFqName(): Boolean =
|
private fun JKSymbol.needFqName(): Boolean {
|
||||||
fqName !in mappedToKotlinFqNames
|
if (this !is JKClassSymbol && !isStaticMember && !isEnumConstant) return false
|
||||||
|
return fqName !in mappedToKotlinFqNames
|
||||||
|
}
|
||||||
|
|
||||||
private fun JKType.renderTypeInfo() {
|
private fun JKType.renderTypeInfo() {
|
||||||
print(elementInfoStorage.getOrCreateInfoForElement(this).render())
|
print(elementInfoStorage.getOrCreateInfoForElement(this).render())
|
||||||
@@ -920,7 +920,7 @@ private class JKPrinter(
|
|||||||
type.renderTypeInfo()
|
type.renderTypeInfo()
|
||||||
when (type) {
|
when (type) {
|
||||||
is JKClassType -> {
|
is JKClassType -> {
|
||||||
renderClassSymbol(type.classReference, owner)
|
renderSymbol(type.classReference, owner)
|
||||||
}
|
}
|
||||||
is JKContextType -> return
|
is JKContextType -> return
|
||||||
is JKStarProjectionType ->
|
is JKStarProjectionType ->
|
||||||
@@ -951,9 +951,9 @@ private class JKPrinter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun renderClassSymbol(classSymbol: JKClassSymbol, owner: JKTreeElement?) {
|
fun renderSymbol(symbol: JKSymbol, owner: JKTreeElement?) {
|
||||||
val needFqName = classSymbol.needFqName() && owner?.isSelectorOfQualifiedExpression() != true
|
val needFqName = symbol.needFqName() && owner?.isSelectorOfQualifiedExpression() != true
|
||||||
val displayName = if (needFqName) classSymbol.getDisplayName() else classSymbol.name
|
val displayName = if (needFqName) symbol.getDisplayName() else symbol.name
|
||||||
printWithNoIndent(displayName.escapedAsQualifiedName())
|
printWithNoIndent(displayName.escapedAsQualifiedName())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.nj2k.conversions
|
||||||
|
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
|
import org.jetbrains.kotlin.nj2k.identifier
|
||||||
|
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseClassSymbol
|
||||||
|
import org.jetbrains.kotlin.nj2k.symbols.isStaticMember
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveRedundantQualifiersForCallsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||||
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
|
if (element !is JKQualifiedExpression) return recurse(element)
|
||||||
|
val needRemoveQualifier = when (val receiver = element.receiver.receiverExpression()) {
|
||||||
|
is JKClassAccessExpression -> receiver.identifier is JKUniverseClassSymbol
|
||||||
|
is JKFieldAccessExpression, is JKCallExpression ->
|
||||||
|
receiver !is JKClassAccessExpression && element.selector.identifier?.isStaticMember == true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if (needRemoveQualifier) {
|
||||||
|
element.invalidate()
|
||||||
|
return recurse(element.selector.withNonCodeElementsFrom(element.receiver).withNonCodeElementsFrom(element))
|
||||||
|
}
|
||||||
|
return recurse(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKExpression.receiverExpression() = when (this) {
|
||||||
|
is JKQualifiedExpression -> selector
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,35 +5,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.conversions
|
package org.jetbrains.kotlin.nj2k.conversions
|
||||||
|
|
||||||
|
|
||||||
import com.intellij.lang.jvm.JvmModifier
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiModifierListOwner
|
|
||||||
import org.jetbrains.kotlin.j2k.getContainingClass
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.nj2k.asQualifierWithThisAsSelector
|
import org.jetbrains.kotlin.nj2k.asQualifierWithThisAsSelector
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKSymbol
|
import org.jetbrains.kotlin.nj2k.symbols.isStaticMember
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|
||||||
|
|
||||||
|
|
||||||
class StaticMemberAccessConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
class StaticMemberAccessConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
val symbol =
|
if (element !is JKQualifiedExpression) return recurse(element)
|
||||||
when (element) {
|
val symbol = when (element) {
|
||||||
is JKFieldAccessExpression -> element.identifier
|
is JKFieldAccessExpression -> element.identifier
|
||||||
is JKCallExpression -> element.identifier
|
is JKCallExpression -> element.identifier
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return recurse(element)
|
} ?: return recurse(element)
|
||||||
if (element.asQualifierWithThisAsSelector() != null) return recurse(element)
|
if (element.asQualifierWithThisAsSelector() != null) return recurse(element)
|
||||||
if (symbol.isStaticMember()) {
|
if (symbol.isStaticMember) {
|
||||||
val containingClassSymbol = symbol.containingClassSymbol() ?: return recurse(element)
|
val containingClassSymbol = symbol.declaredIn as? JKClassSymbol ?: return recurse(element)
|
||||||
return recurse(
|
return recurse(
|
||||||
JKQualifiedExpression(
|
JKQualifiedExpression(
|
||||||
JKClassAccessExpression(containingClassSymbol),
|
JKClassAccessExpression(containingClassSymbol),
|
||||||
@@ -43,39 +31,5 @@ class StaticMemberAccessConversion(context: NewJ2kConverterContext) : RecursiveA
|
|||||||
}
|
}
|
||||||
return recurse(element)
|
return recurse(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKSymbol.isStaticMember(): Boolean = when (val target = target) {
|
|
||||||
is PsiModifierListOwner -> target.hasModifier(JvmModifier.STATIC)
|
|
||||||
is KtElement -> target.getStrictParentOfType<KtClassOrObject>()
|
|
||||||
?.safeAs<KtObjectDeclaration>()
|
|
||||||
?.isCompanion() == true
|
|
||||||
is JKTreeElement ->
|
|
||||||
target.safeAs<JKOtherModifiersOwner>()?.hasOtherModifier(OtherModifier.STATIC) == true
|
|
||||||
|| target.parentOfType<JKClass>()?.classKind == JKClass.ClassKind.OBJECT
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKSymbol.containingClassSymbol(): JKClassSymbol? {
|
|
||||||
val target = target
|
|
||||||
return when (target) {
|
|
||||||
is KtElement ->
|
|
||||||
target.getStrictParentOfType<KtClassOrObject>()?.let { klass ->
|
|
||||||
if (klass is KtObjectDeclaration && klass.isCompanion()) klass.containingClass()
|
|
||||||
else klass
|
|
||||||
}?.let { symbolProvider.provideDirectSymbol(it) }
|
|
||||||
|
|
||||||
is PsiElement -> target.getContainingClass()?.let {
|
|
||||||
symbolProvider.provideDirectSymbol(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
is JKTreeElement ->
|
|
||||||
target.parentOfType<JKClass>()?.let { klass ->
|
|
||||||
if (klass.classKind == JKClass.ClassKind.COMPANION) klass.parentOfType<JKClass>()
|
|
||||||
else klass
|
|
||||||
}?.let { symbolProvider.provideUniverseSymbol(it) }
|
|
||||||
else -> error("bad isStaticMember")
|
|
||||||
} as JKClassSymbol?
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,16 @@ import org.jetbrains.kotlin.nj2k.tree.*
|
|||||||
import org.jetbrains.kotlin.nj2k.types.*
|
import org.jetbrains.kotlin.nj2k.types.*
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
|
||||||
class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
class TypeMappingConversion(
|
||||||
|
context: NewJ2kConverterContext,
|
||||||
|
inline val filter: (typeElement: JKTypeElement) -> Boolean = { true }
|
||||||
|
) : RecursiveApplicableConversionBase(context) {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
when (element) {
|
when (element) {
|
||||||
is JKTypeElement -> {
|
is JKTypeElement -> {
|
||||||
element.type = element.type.mapType(element)
|
if (filter(element)) {
|
||||||
|
element.type = element.type.mapType(element)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is JKNewExpression -> {
|
is JKNewExpression -> {
|
||||||
val newClassSymbol = element.classSymbol.mapClassSymbol()
|
val newClassSymbol = element.classSymbol.mapClassSymbol()
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.intellij.psi.tree.TokenSet
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase
|
import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
|
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
|
||||||
|
import org.jetbrains.kotlin.nj2k.symbols.JKSymbol
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedMethod
|
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedMethod
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
|
|
||||||
@@ -339,3 +340,16 @@ fun JKClass.isLocalClass(): Boolean =
|
|||||||
|
|
||||||
val JKClass.declarationList: List<JKDeclaration>
|
val JKClass.declarationList: List<JKDeclaration>
|
||||||
get() = classBody.declarations
|
get() = classBody.declarations
|
||||||
|
|
||||||
|
val JKTreeElement.identifier: JKSymbol?
|
||||||
|
get() = when (this) {
|
||||||
|
is JKFieldAccessExpression -> identifier
|
||||||
|
is JKCallExpression -> identifier
|
||||||
|
is JKClassAccessExpression -> identifier
|
||||||
|
is JKPackageAccessExpression -> identifier
|
||||||
|
is JKNewExpression -> classSymbol
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
val JKClass.isObjectOrCompanionObject
|
||||||
|
get() = classKind == JKClass.ClassKind.OBJECT || classKind == JKClass.ClassKind.COMPANION
|
||||||
@@ -17,7 +17,10 @@ sealed class JKClassSymbol : JKSymbol
|
|||||||
class JKUniverseClassSymbol(override val typeFactory: JKTypeFactory) : JKClassSymbol(), JKUniverseSymbol<JKClass> {
|
class JKUniverseClassSymbol(override val typeFactory: JKTypeFactory) : JKClassSymbol(), JKUniverseSymbol<JKClass> {
|
||||||
override lateinit var target: JKClass
|
override lateinit var target: JKClass
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = target.name.value
|
get() = when {
|
||||||
|
target.classKind == JKClass.ClassKind.COMPANION -> "Companion"
|
||||||
|
else -> target.name.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKMultiverseClassSymbol(
|
class JKMultiverseClassSymbol(
|
||||||
|
|||||||
@@ -6,15 +6,25 @@
|
|||||||
package org.jetbrains.kotlin.nj2k.symbols
|
package org.jetbrains.kotlin.nj2k.symbols
|
||||||
|
|
||||||
import com.intellij.psi.PsiPackage
|
import com.intellij.psi.PsiPackage
|
||||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
import org.jetbrains.kotlin.nj2k.tree.JKPackageDeclaration
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||||
|
|
||||||
|
|
||||||
sealed class JKPackageSymbol : JKSymbol {
|
sealed class JKPackageSymbol : JKSymbol
|
||||||
abstract override val target: PsiPackage
|
|
||||||
}
|
|
||||||
|
|
||||||
class JKMultiversePackageSymbol(
|
class JKMultiversePackageSymbol(
|
||||||
override val target: PsiPackage,
|
override val target: PsiPackage,
|
||||||
override val typeFactory: JKTypeFactory
|
override val typeFactory: JKTypeFactory
|
||||||
) : JKPackageSymbol(), JKMultiverseSymbol<PsiPackage>
|
) : JKPackageSymbol(), JKMultiverseSymbol<PsiPackage> {
|
||||||
|
override val declaredIn: JKSymbol?
|
||||||
|
get() = null
|
||||||
|
}
|
||||||
|
|
||||||
|
class JKUniversePackageSymbol(
|
||||||
|
override val typeFactory: JKTypeFactory
|
||||||
|
) : JKPackageSymbol(), JKUniverseSymbol<JKPackageDeclaration> {
|
||||||
|
override lateinit var target: JKPackageDeclaration
|
||||||
|
|
||||||
|
override val declaredIn: JKSymbol?
|
||||||
|
get() = null
|
||||||
|
}
|
||||||
@@ -48,7 +48,10 @@ interface JKUniverseSymbol<T : JKDeclaration> : JKSymbol {
|
|||||||
get() = target.name.value
|
get() = target.name.value
|
||||||
|
|
||||||
override val declaredIn: JKSymbol?
|
override val declaredIn: JKSymbol?
|
||||||
get() = target.parentOfType<JKDeclaration>()?.let { symbolProvider.symbolsByJK[it] }
|
get() = target.parentOfType<JKDeclaration>()?.let { symbolProvider.provideUniverseSymbol(it) }
|
||||||
|
?: target.parentOfType<JKFile>()?.packageDeclaration
|
||||||
|
?.takeIf { it.name.value.isNotEmpty() }
|
||||||
|
?.let { symbolProvider.provideUniverseSymbol(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKMultiverseSymbol<T> : JKSymbol where T : PsiNamedElement, T : PsiElement {
|
interface JKMultiverseSymbol<T> : JKSymbol where T : PsiNamedElement, T : PsiElement {
|
||||||
|
|||||||
@@ -5,18 +5,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.symbols
|
package org.jetbrains.kotlin.nj2k.symbols
|
||||||
|
|
||||||
|
import com.intellij.lang.jvm.JvmModifier
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiEnumConstant
|
||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.PsiModifier
|
import com.intellij.psi.PsiModifierListOwner
|
||||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsNoWrapping
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsNoWrapping
|
||||||
|
import org.jetbrains.kotlin.nj2k.isObjectOrCompanionObject
|
||||||
import org.jetbrains.kotlin.nj2k.psi
|
import org.jetbrains.kotlin.nj2k.psi
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKType
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.nj2k.types.arrayInnerType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
|
||||||
@@ -24,9 +24,10 @@ val JKSymbol.isUnresolved
|
|||||||
get() = this is JKUnresolvedSymbol
|
get() = this is JKUnresolvedSymbol
|
||||||
|
|
||||||
fun JKSymbol.getDisplayName(): String {
|
fun JKSymbol.getDisplayName(): String {
|
||||||
|
fun JKSymbol.isDisplayable() = this is JKClassSymbol || this is JKPackageSymbol
|
||||||
if (this !is JKUniverseSymbol<*>) return fqName
|
if (this !is JKUniverseSymbol<*>) return fqName
|
||||||
return generateSequence(declaredIn as? JKUniverseClassSymbol) { symbol ->
|
return generateSequence(declaredIn?.takeIf { it.isDisplayable() }) { symbol ->
|
||||||
symbol.declaredIn.safeAs<JKUniverseClassSymbol>()?.takeIf { !it.target.hasOtherModifier(OtherModifier.INNER) }
|
symbol.declaredIn?.takeIf { it.isDisplayable() }
|
||||||
}.fold(name) { acc, symbol -> "${symbol.name}.$acc" }
|
}.fold(name) { acc, symbol -> "${symbol.name}.$acc" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,3 +46,23 @@ fun JKSymbol.deepestFqName(): String? {
|
|||||||
}
|
}
|
||||||
return target.deepestFqNameForTarget() ?: fqName
|
return target.deepestFqNameForTarget() ?: fqName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val JKSymbol.isStaticMember
|
||||||
|
get() = when (val target = target) {
|
||||||
|
is PsiModifierListOwner -> target.hasModifier(JvmModifier.STATIC)
|
||||||
|
is KtElement -> target.getStrictParentOfType<KtClassOrObject>()
|
||||||
|
?.safeAs<KtObjectDeclaration>()
|
||||||
|
?.isCompanion() == true
|
||||||
|
is JKTreeElement ->
|
||||||
|
target.safeAs<JKOtherModifiersOwner>()?.hasOtherModifier(OtherModifier.STATIC) == true
|
||||||
|
|| target.parentOfType<JKClass>()?.isObjectOrCompanionObject == true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
val JKSymbol.isEnumConstant
|
||||||
|
get() = when (target) {
|
||||||
|
is JKEnumConstant -> true
|
||||||
|
is PsiEnumConstant -> true
|
||||||
|
is KtEnumEntry -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ class JKInheritanceInfo(
|
|||||||
override fun accept(visitor: JKVisitor) = visitor.visitInheritanceInfo(this)
|
override fun accept(visitor: JKVisitor) = visitor.visitInheritanceInfo(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKPackageDeclaration(name: JKNameIdentifier) : JKTreeElement() {
|
class JKPackageDeclaration(name: JKNameIdentifier) : JKDeclaration() {
|
||||||
var name: JKNameIdentifier by child(name)
|
override var name: JKNameIdentifier by child(name)
|
||||||
override fun accept(visitor: JKVisitor) = visitor.visitPackageDeclaration(this)
|
override fun accept(visitor: JKVisitor) = visitor.visitPackageDeclaration(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@file:JvmName("Bar")
|
||||||
|
package p
|
||||||
|
fun bar() {}
|
||||||
|
fun bar(x:Int) {}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import static p.Bar.bar;
|
||||||
|
|
||||||
|
class Impl {
|
||||||
|
void foo() {
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import p.bar
|
||||||
|
|
||||||
|
internal class Impl {
|
||||||
|
fun foo() {
|
||||||
|
bar()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
public class Rectangle {
|
||||||
|
public static int x = 0;
|
||||||
|
public int y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Rectangle rectangle = new Rectangle();
|
||||||
|
rectangle.x = 1;
|
||||||
|
rectangle.y = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
class Rectangle {
|
||||||
|
var y = 0
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var x = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Main {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val rectangle = Rectangle()
|
||||||
|
Rectangle.x = 1
|
||||||
|
rectangle.y = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
public class Base {
|
||||||
|
public static void foo() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Derived extends Base {
|
||||||
|
}
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
public static void test() {
|
||||||
|
Derived.foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base()
|
||||||
|
object User {
|
||||||
|
fun test() {
|
||||||
|
Base.foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -4475,6 +4475,21 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
|||||||
public void testPrivateStaticMethods4() throws Exception {
|
public void testPrivateStaticMethods4() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/staticMembers/PrivateStaticMethods4.java");
|
runTest("nj2k/testData/newJ2k/staticMembers/PrivateStaticMethods4.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StaticImport.java")
|
||||||
|
public void testStaticImport() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/staticMembers/StaticImport.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StaticMemmberAccessedViaInstance.java")
|
||||||
|
public void testStaticMemmberAccessedViaInstance() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/staticMembers/StaticMemmberAccessedViaInstance.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("StaticQualifiedByInheritor.java")
|
||||||
|
public void testStaticQualifiedByInheritor() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/staticMembers/StaticQualifiedByInheritor.java");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("nj2k/testData/newJ2k/strings")
|
@TestMetadata("nj2k/testData/newJ2k/strings")
|
||||||
|
|||||||
Reference in New Issue
Block a user