mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin] J2K: static method referenced by Java is converted without @JvmStatic in case it is overloaded
^KTIJ-15669 Fixed GitOrigin-RevId: 84bd74031913674b0e75ffbc94fc04c286e1025e
This commit is contained in:
committed by
intellij-monorepo-bot
parent
026fe34f7e
commit
c375229dc7
+37
-14
@@ -5,9 +5,7 @@ package org.jetbrains.kotlin.nj2k.externalCodeProcessing
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMember
|
||||
import com.intellij.psi.SmartPointerManager
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.idea.base.psi.kotlinFqName
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.j2k.ExternalCodeProcessing
|
||||
@@ -18,36 +16,61 @@ import org.jetbrains.kotlin.nj2k.KotlinNJ2KBundle
|
||||
import org.jetbrains.kotlin.nj2k.fqNameWithoutCompanions
|
||||
import org.jetbrains.kotlin.nj2k.psi
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKDeclaration
|
||||
import org.jetbrains.kotlin.nj2k.types.typeFqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
||||
|
||||
|
||||
class NewExternalCodeProcessing(
|
||||
private val referenceSearcher: ReferenceSearcher,
|
||||
private val inConversionContext: (PsiElement) -> Boolean
|
||||
) : ExternalCodeProcessing {
|
||||
private val members = mutableMapOf<FqName, JKMemberData>()
|
||||
|
||||
fun addMember(data: JKMemberData) {
|
||||
members[data.fqName ?: return] = data
|
||||
private sealed class MemberKey {
|
||||
data class MethodKey(val fqName: FqName, val parameters: List<FqName>) : MemberKey()
|
||||
data class FieldKey(val fqName: FqName) : MemberKey()
|
||||
}
|
||||
|
||||
fun getMember(element: JKDeclaration) =
|
||||
element.psi<PsiMember>()?.kotlinFqName?.let(members::get)
|
||||
|
||||
fun getMember(fqName: FqName) =
|
||||
members[fqName]
|
||||
private val members = mutableMapOf<MemberKey, JKMemberData>()
|
||||
|
||||
fun isExternalProcessingNeeded(): Boolean =
|
||||
members.values.any { it.searchingNeeded }
|
||||
|
||||
fun addMember(data: JKMemberData) {
|
||||
val key = data.buildKey() ?: return
|
||||
members[key] = data
|
||||
}
|
||||
|
||||
fun getMember(element: JKDeclaration): JKMemberData? = members[element.psi<PsiMember>()?.buildKey()]
|
||||
fun getMember(element: KtDeclaration): JKMemberData? = members[element.buildKey()]
|
||||
|
||||
private fun JKMemberData.buildKey(): MemberKey? {
|
||||
val fqName = this.fqName ?: return null
|
||||
return when (this) {
|
||||
is JKMethodData -> MemberKey.MethodKey(fqName, this.javaElement.parameterList.parameters.mapNotNull { it.typeFqName() })
|
||||
else -> MemberKey.FieldKey(fqName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiMember.buildKey(): MemberKey? {
|
||||
val fqName = this.kotlinFqName ?: return null
|
||||
return when (this) {
|
||||
is PsiMethod -> MemberKey.MethodKey(fqName, this.parameterList.parameters.mapNotNull { it.typeFqName() })
|
||||
else -> MemberKey.FieldKey(fqName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtDeclaration.buildKey() = when (this) {
|
||||
is KtNamedFunction -> MemberKey.MethodKey(this.fqNameWithoutCompanions, this.valueParameters.mapNotNull { it.typeFqName() })
|
||||
else -> MemberKey.FieldKey(this.fqNameWithoutCompanions)
|
||||
}
|
||||
|
||||
private fun List<KtFile>.bindJavaDeclarationsToConvertedKotlinOnes() {
|
||||
forEach { file ->
|
||||
file.forEachDescendantOfType<KtNamedDeclaration> { declaration ->
|
||||
val member = getMember(declaration.fqNameWithoutCompanions) ?: return@forEachDescendantOfType
|
||||
val member = getMember(declaration) ?: return@forEachDescendantOfType
|
||||
when {
|
||||
member is JKFieldData ->
|
||||
member.kotlinElementPointer = SmartPointerManager.createPointer(declaration)
|
||||
|
||||
member is JKMethodData && declaration is KtNamedFunction ->
|
||||
member.kotlinElementPointer = SmartPointerManager.createPointer(declaration)
|
||||
}
|
||||
|
||||
@@ -5,19 +5,25 @@ package org.jetbrains.kotlin.nj2k.types
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiParameter
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.impl.compiled.ClsMethodImpl
|
||||
import com.intellij.psi.impl.source.PsiAnnotationMethodImpl
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.idea.base.psi.kotlinFqName
|
||||
import org.jetbrains.kotlin.idea.base.utils.fqname.fqName
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
@@ -37,6 +43,9 @@ val PsiType.isKotlinFunctionalType: Boolean
|
||||
return functionalTypeRegex.matches(fqName.asString())
|
||||
}
|
||||
|
||||
fun PsiParameter.typeFqName(): FqName? = this.getParameterDescriptor()?.type?.fqName
|
||||
fun KtParameter.typeFqName(): FqName? = this.descriptor?.type?.fqName
|
||||
|
||||
private val functionalTypeRegex = """(kotlin\.jvm\.functions|kotlin)\.Function[\d+]""".toRegex()
|
||||
|
||||
fun KtTypeReference.toJK(typeFactory: JKTypeFactory): JKType? =
|
||||
|
||||
+5
@@ -83,6 +83,11 @@ public class NewJavaToKotlinConverterMultiFileTestGenerated extends AbstractNewJ
|
||||
runTest("testData/multiFile/ProtectedVisibility/");
|
||||
}
|
||||
|
||||
@TestMetadata("StaticAnnotation")
|
||||
public void testStaticAnnotation() throws Exception {
|
||||
runTest("testData/multiFile/StaticAnnotation/");
|
||||
}
|
||||
|
||||
@TestMetadata("ToCompanionObject")
|
||||
public void testToCompanionObject() throws Exception {
|
||||
runTest("testData/multiFile/ToCompanionObject/");
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
public class ConvertMe1 {
|
||||
public static void foo(String a, String b) {}
|
||||
public static void foo(String a) {}
|
||||
public static void foo(int... values) {}
|
||||
public static void foo() {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
object ConvertMe1 {
|
||||
@JvmStatic
|
||||
fun foo(a: String?, b: String?) {}
|
||||
@JvmStatic
|
||||
fun foo(a: String?) {}
|
||||
@JvmStatic
|
||||
fun foo(vararg values: Int) {}
|
||||
fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
public class ConvertMe2 {
|
||||
public static void foo(String a, int b) {}
|
||||
public static void foo(int a, String b) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
object ConvertMe2 {
|
||||
@JvmStatic
|
||||
fun foo(a: String?, b: Int) {}
|
||||
fun foo(a: Int, b: String?) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
public class ConvertMe3 {
|
||||
public static void foo(String a, int b) {}
|
||||
public static void foo(int a, String b) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
object ConvertMe3 {
|
||||
fun foo(a: String?, b: Int) {}
|
||||
@JvmStatic
|
||||
fun foo(a: Int, b: String?) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
public class ConvertMe4 {
|
||||
public static void foo(String a, int b) {}
|
||||
public static void foo(int a, String b) {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
object ConvertMe4 {
|
||||
@JvmStatic
|
||||
fun foo(a: String?, b: Int) {}
|
||||
@JvmStatic
|
||||
fun foo(a: Int, b: String?) {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
public class ConvertMe5 {
|
||||
public static void foo(int... arguments) {}
|
||||
public static void foo(int argument) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
object ConvertMe5 {
|
||||
fun foo(vararg arguments: Int) {}
|
||||
@JvmStatic
|
||||
fun foo(argument: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import java.util.List;
|
||||
|
||||
public class ConvertMe6 {
|
||||
public static void foo(SimpleClass a) {}
|
||||
public static void foo(SimpleClass a, SimpleClass b) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
object ConvertMe6 {
|
||||
@JvmStatic
|
||||
fun foo(a: SimpleClass?) {}
|
||||
fun foo(a: SimpleClass?, b: SimpleClass?) {}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import java.util.List;
|
||||
|
||||
public class Referrer {
|
||||
public void ref1() {
|
||||
ConvertMe1.foo("A", "B");
|
||||
ConvertMe1.foo("A");
|
||||
ConvertMe1.foo(1);
|
||||
}
|
||||
|
||||
public void ref2() {
|
||||
ConvertMe2.foo("A", 2);
|
||||
}
|
||||
|
||||
public void ref3() {
|
||||
ConvertMe3.foo(2, "A");
|
||||
}
|
||||
|
||||
public void ref4() {
|
||||
ConvertMe4.foo("A", 2);
|
||||
ConvertMe4.foo(2, "A");
|
||||
}
|
||||
|
||||
public void ref5() {
|
||||
ConvertMe5.foo(1);
|
||||
}
|
||||
|
||||
public void ref6() {
|
||||
SimpleClass simpleClass = new SimpleClass();
|
||||
ConvertMe6.foo(simpleClass);
|
||||
}
|
||||
}
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
import java.util.List;
|
||||
|
||||
public class Referrer {
|
||||
public void ref1() {
|
||||
ConvertMe1.foo("A", "B");
|
||||
ConvertMe1.foo("A");
|
||||
ConvertMe1.foo(1);
|
||||
}
|
||||
|
||||
public void ref2() {
|
||||
ConvertMe2.foo("A", 2);
|
||||
}
|
||||
|
||||
public void ref3() {
|
||||
ConvertMe3.foo(2, "A");
|
||||
}
|
||||
|
||||
public void ref4() {
|
||||
ConvertMe4.foo("A", 2);
|
||||
ConvertMe4.foo(2, "A");
|
||||
}
|
||||
|
||||
public void ref5() {
|
||||
ConvertMe5.foo(1);
|
||||
}
|
||||
|
||||
public void ref6() {
|
||||
SimpleClass simpleClass = new SimpleClass();
|
||||
ConvertMe6.foo(simpleClass);
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
public class SimpleClass {
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
public class SimpleClass {
|
||||
}
|
||||
+5
-9
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.idea.util.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.asGetterName
|
||||
@@ -640,8 +639,8 @@ private class ConvertGettersAndSettersToPropertyStatefulProcessing(
|
||||
}
|
||||
|
||||
val propertyInfo = when (property) {
|
||||
is RealProperty -> property.property.fqNameWithoutCompanions.let(externalCodeUpdater::getMember)
|
||||
is MergedProperty -> property.mergeTo.fqNameWithoutCompanions.let(externalCodeUpdater::getMember)
|
||||
is RealProperty -> property.property.let(externalCodeUpdater::getMember)
|
||||
is MergedProperty -> property.mergeTo.let(externalCodeUpdater::getMember)
|
||||
is FakeProperty -> JKFakeFieldData(
|
||||
isStatic = klass is KtObjectDeclaration,
|
||||
kotlinElementPointer = null,
|
||||
@@ -650,18 +649,15 @@ private class ConvertGettersAndSettersToPropertyStatefulProcessing(
|
||||
).also { externalCodeUpdater.addMember(it) }
|
||||
}?.also { it.name = property.name } as? JKFieldData
|
||||
|
||||
val getterFqName = getter.safeAs<RealGetter>()?.function?.fqNameWithoutCompanions
|
||||
val setterFqName = setter.safeAs<RealSetter>()?.function?.fqNameWithoutCompanions
|
||||
|
||||
fun FqName.setPropertyInfo(info: JKFieldData) {
|
||||
fun KtDeclaration.setPropertyInfo(info: JKFieldData) {
|
||||
externalCodeUpdater.getMember(this)?.safeAs<JKMethodData>()?.let {
|
||||
it.usedAsAccessorOfProperty = info
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyInfo != null) {
|
||||
getterFqName?.setPropertyInfo(propertyInfo)
|
||||
setterFqName?.setPropertyInfo(propertyInfo)
|
||||
getter.safeAs<RealGetter>()?.function?.setPropertyInfo(propertyInfo)
|
||||
setter.safeAs<RealSetter>()?.function?.setPropertyInfo(propertyInfo)
|
||||
}
|
||||
|
||||
val isOpen = getter.safeAs<RealGetter>()?.function?.hasModifier(KtTokens.OPEN_KEYWORD) == true
|
||||
|
||||
Reference in New Issue
Block a user