[lc] decompiled: support stub search for top level callable
^KT-53934
This commit is contained in:
+9
-11
@@ -13,11 +13,9 @@ import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
|
|||||||
import org.jetbrains.kotlin.asJava.syntheticAccessors
|
import org.jetbrains.kotlin.asJava.syntheticAccessors
|
||||||
import org.jetbrains.kotlin.load.kotlin.MemberSignature
|
import org.jetbrains.kotlin.load.kotlin.MemberSignature
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
|
||||||
import org.jetbrains.kotlin.psi.allConstructors
|
|
||||||
import org.jetbrains.kotlin.type.MapPsiToAsmDesc
|
import org.jetbrains.kotlin.type.MapPsiToAsmDesc
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
abstract class KotlinDeclarationInCompiledFileSearcher {
|
abstract class KotlinDeclarationInCompiledFileSearcher {
|
||||||
abstract fun findDeclarationInCompiledFile(file: KtClsFile, member: PsiMember, signature: MemberSignature): KtDeclaration?
|
abstract fun findDeclarationInCompiledFile(file: KtClsFile, member: PsiMember, signature: MemberSignature): KtDeclaration?
|
||||||
@@ -46,23 +44,23 @@ abstract class KotlinDeclarationInCompiledFileSearcher {
|
|||||||
member: PsiMember,
|
member: PsiMember,
|
||||||
memberName: String,
|
memberName: String,
|
||||||
): KtDeclaration? {
|
): KtDeclaration? {
|
||||||
val topClassOrObject = file.declarations.singleOrNull() as? KtClassOrObject
|
val classOrFile: KtDeclarationContainer = file.declarations.singleOrNull() as? KtClassOrObject ?: file
|
||||||
val container: KtClassOrObject = if (relativeClassName.isEmpty())
|
val container: KtDeclarationContainer = if (relativeClassName.isEmpty())
|
||||||
topClassOrObject
|
classOrFile
|
||||||
else {
|
else {
|
||||||
relativeClassName.fold(topClassOrObject) { classOrObject, name ->
|
relativeClassName.fold(classOrFile) { declaration: KtDeclarationContainer?, name: Name ->
|
||||||
classOrObject?.declarations?.singleOrNull { it.name == name.asString() } as? KtClassOrObject
|
declaration?.declarations?.singleOrNull() { it is KtClassOrObject && it.name == name.asString() } as? KtClassOrObject
|
||||||
}
|
}
|
||||||
} ?: return null
|
} ?: return null
|
||||||
|
|
||||||
if (member is PsiMethod && member.isConstructor) {
|
if (member is PsiMethod && member.isConstructor) {
|
||||||
return container.takeIf { it.name == memberName }?.allConstructors?.singleOrNull()
|
return container.safeAs<KtClassOrObject>()?.takeIf { it.name == memberName }?.allConstructors?.singleOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
val declarations = container.declarations
|
val declarations = container.declarations
|
||||||
return when (member) {
|
return when (member) {
|
||||||
is PsiMethod -> {
|
is PsiMethod -> {
|
||||||
val names = member.syntheticAccessors.map(Name::asString) + memberName
|
val names = member.syntheticAccessors(withoutOverrideCheck = true).map(Name::asString) + memberName
|
||||||
declarations.singleOrNull { it.name in names }
|
declarations.singleOrNull { it.name in names }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -269,7 +269,11 @@ private val PsiMethod.canBeSetter: Boolean
|
|||||||
get() = JvmAbi.isSetterName(name) && parameters.size == 1 && returnTypeElement?.textMatches("void") != false
|
get() = JvmAbi.isSetterName(name) && parameters.size == 1 && returnTypeElement?.textMatches("void") != false
|
||||||
|
|
||||||
private val PsiMethod.probablyCanHaveSyntheticAccessors: Boolean
|
private val PsiMethod.probablyCanHaveSyntheticAccessors: Boolean
|
||||||
get() = canHaveOverride && !hasTypeParameters() && !isFinalProperty
|
get() = probablyCanHaveSyntheticAccessors()
|
||||||
|
|
||||||
|
private fun PsiMethod.probablyCanHaveSyntheticAccessors(withoutOverrideCheck: Boolean = false): Boolean {
|
||||||
|
return (withoutOverrideCheck || canHaveOverride) && !hasTypeParameters() && !isFinalProperty
|
||||||
|
}
|
||||||
|
|
||||||
private val PsiMethod.getterName: Name? get() = propertyNameByGetMethodName(Name.identifier(name))
|
private val PsiMethod.getterName: Name? get() = propertyNameByGetMethodName(Name.identifier(name))
|
||||||
private val PsiMethod.setterNames: Collection<Name>? get() = propertyNamesBySetMethodName(Name.identifier(name)).takeIf { it.isNotEmpty() }
|
private val PsiMethod.setterNames: Collection<Name>? get() = propertyNamesBySetMethodName(Name.identifier(name)).takeIf { it.isNotEmpty() }
|
||||||
@@ -284,16 +288,17 @@ private val PsiMethod.isFinalProperty: Boolean
|
|||||||
|
|
||||||
private val PsiMethod.isTopLevelDeclaration: Boolean get() = unwrapped?.isTopLevelKtOrJavaMember() == true
|
private val PsiMethod.isTopLevelDeclaration: Boolean get() = unwrapped?.isTopLevelKtOrJavaMember() == true
|
||||||
|
|
||||||
val PsiMethod.syntheticAccessors: Collection<Name>
|
val PsiMethod.syntheticAccessors: Collection<Name> get() = syntheticAccessors()
|
||||||
get() {
|
|
||||||
if (!probablyCanHaveSyntheticAccessors) return emptyList()
|
|
||||||
|
|
||||||
return when {
|
fun PsiMethod.syntheticAccessors(withoutOverrideCheck: Boolean = false): Collection<Name> {
|
||||||
canBeGetter -> listOfNotNull(getterName)
|
if (!probablyCanHaveSyntheticAccessors(withoutOverrideCheck)) return emptyList()
|
||||||
canBeSetter -> setterNames.orEmpty()
|
|
||||||
else -> emptyList()
|
return when {
|
||||||
}
|
canBeGetter -> listOfNotNull(getterName)
|
||||||
|
canBeSetter -> setterNames.orEmpty()
|
||||||
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val PsiMethod.canHaveSyntheticAccessors: Boolean get() = probablyCanHaveSyntheticAccessors && (canBeGetter || canBeSetter)
|
val PsiMethod.canHaveSyntheticAccessors: Boolean get() = probablyCanHaveSyntheticAccessors && (canBeGetter || canBeSetter)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user