Return Kotlin fields and methods through KotlinShortNameCache
#KT-12205 Fixed
This commit is contained in:
committed by
Dmitry Jemerov
parent
b06bdcef75
commit
18feb8f622
@@ -16,14 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.java.stubs.PsiClassStub
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.stubs.PsiFileStub
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
@@ -31,6 +29,7 @@ import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues
|
||||
|
||||
object LightClassUtil {
|
||||
|
||||
@@ -53,9 +52,11 @@ object LightClassUtil {
|
||||
|
||||
fun getLightClassAccessorMethods(accessor: KtPropertyAccessor): List<PsiMethod> {
|
||||
val property = accessor.getNonStrictParentOfType<KtProperty>() ?: return emptyList()
|
||||
val wrappers = getPsiMethodWrappers(property, true)
|
||||
return wrappers.filter { wrapper -> (accessor.isGetter && !JvmAbi.isSetterName(wrapper.name)) ||
|
||||
(accessor.isSetter && JvmAbi.isSetterName(wrapper.name)) }
|
||||
val wrappers = getPsiMethodWrappers(property)
|
||||
return wrappers.filter { wrapper ->
|
||||
(accessor.isGetter && !JvmAbi.isSetterName(wrapper.name)) ||
|
||||
(accessor.isSetter && JvmAbi.isSetterName(wrapper.name))
|
||||
}.toList()
|
||||
}
|
||||
|
||||
fun getLightFieldForCompanionObject(companionObject: KtClassOrObject): PsiField? {
|
||||
@@ -120,36 +121,16 @@ object LightClassUtil {
|
||||
}
|
||||
|
||||
fun getLightClassMethods(function: KtFunction): List<PsiMethod> {
|
||||
return getPsiMethodWrappers(function, true)
|
||||
return getPsiMethodWrappers(function).toList()
|
||||
}
|
||||
|
||||
private fun getPsiMethodWrapper(declaration: KtDeclaration): PsiMethod? {
|
||||
return getPsiMethodWrappers(declaration, false).firstOrNull()
|
||||
return getPsiMethodWrappers(declaration).firstOrNull()
|
||||
}
|
||||
|
||||
private fun getPsiMethodWrappers(declaration: KtDeclaration, collectAll: Boolean): List<PsiMethod> {
|
||||
val psiClass = getWrappingClass(declaration) ?: return emptyList()
|
||||
|
||||
val methods = SmartList<PsiMethod>()
|
||||
for (method in psiClass.methods.asList()) {
|
||||
try {
|
||||
if (method is KtLightMethod && method.kotlinOrigin === declaration) {
|
||||
methods.add(method)
|
||||
if (!collectAll) {
|
||||
return methods
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
throw IllegalStateException(
|
||||
"Error while wrapping declaration " + declaration.name + "Context\n:" + method, e)
|
||||
}
|
||||
}
|
||||
|
||||
return methods
|
||||
private fun getPsiMethodWrappers(declaration: KtDeclaration): Sequence<PsiMethod> {
|
||||
return getWrappingClasses(declaration).flatMap { it.methods.asSequence() }
|
||||
.filter { method -> method is KtLightMethod && method.kotlinOrigin === declaration }
|
||||
}
|
||||
|
||||
private fun getWrappingClass(declaration: KtDeclaration): PsiClass? {
|
||||
@@ -185,6 +166,15 @@ object LightClassUtil {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getWrappingClasses(declaration: KtDeclaration): Sequence<PsiClass> {
|
||||
val wrapperClass = getWrappingClass(declaration) ?: return emptySequence()
|
||||
val wrapperClassOrigin = (wrapperClass as KtLightClass).kotlinOrigin
|
||||
if (wrapperClassOrigin is KtObjectDeclaration && wrapperClassOrigin.isCompanion()) {
|
||||
return sequenceOfLazyValues({ wrapperClass }, { wrapperClass.parent as PsiClass })
|
||||
}
|
||||
return sequenceOf(wrapperClass)
|
||||
}
|
||||
|
||||
fun canGenerateLightClass(declaration: KtDeclaration): Boolean {
|
||||
//noinspection unchecked
|
||||
return PsiTreeUtil.getParentOfType(declaration, KtFunction::class.java, KtProperty::class.java) == null
|
||||
@@ -197,7 +187,7 @@ object LightClassUtil {
|
||||
var setterWrapper = specialSetter
|
||||
val additionalAccessors = arrayListOf<PsiMethod>()
|
||||
|
||||
for (wrapper in getPsiMethodWrappers(ktDeclaration, true)) {
|
||||
for (wrapper in getPsiMethodWrappers(ktDeclaration)) {
|
||||
if (wrapper !is KtLightMethod) continue
|
||||
|
||||
if (wrapper.isSetter) {
|
||||
@@ -209,7 +199,7 @@ object LightClassUtil {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (getterWrapper == null || getterWrapper == specialGetter) {
|
||||
if (getterWrapper == null || getterWrapper === specialGetter) {
|
||||
getterWrapper = wrapper
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiField
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.impl.PsiVariableEx
|
||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
@@ -31,4 +32,6 @@ interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiNamedElemen
|
||||
|
||||
interface KtLightDeclaration<out T: KtDeclaration, out D: PsiElement>: KtLightElement<T, D>
|
||||
|
||||
interface KtLightField : PsiField, KtLightDeclaration<KtDeclaration, PsiField>, PsiVariableEx
|
||||
interface KtLightField : PsiField, KtLightDeclaration<KtDeclaration, PsiField>, PsiVariableEx {
|
||||
val lightMemberOrigin: LightMemberOrigin?
|
||||
}
|
||||
+22
-1
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.navigation.ItemPresentation
|
||||
import com.intellij.navigation.ItemPresentationProviders
|
||||
import com.intellij.navigation.NavigationItem
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiVariableEx
|
||||
@@ -30,10 +33,11 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
// Copied from com.intellij.psi.impl.light.LightField
|
||||
sealed class KtLightFieldImpl(
|
||||
private val lightMemberOrigin: LightMemberOrigin?,
|
||||
override val lightMemberOrigin: LightMemberOrigin?,
|
||||
override val clsDelegate: PsiField,
|
||||
private val containingClass: KtLightClass
|
||||
) : LightElement(clsDelegate.manager, KotlinLanguage.INSTANCE), KtLightField {
|
||||
@@ -44,6 +48,8 @@ sealed class KtLightFieldImpl(
|
||||
|
||||
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
|
||||
|
||||
override fun getPresentation(): ItemPresentation? = (kotlinOrigin ?: this).let { ItemPresentationProviders.getItemPresentation(it) }
|
||||
|
||||
override fun getName() = clsDelegate.name
|
||||
|
||||
override fun getNameIdentifier() = lightIdentifier
|
||||
@@ -92,6 +98,20 @@ sealed class KtLightFieldImpl(
|
||||
|
||||
override fun toString(): String = "${this.javaClass.simpleName}:$name"
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
other is KtLightField &&
|
||||
name == other.name &&
|
||||
lightMemberOrigin == other.lightMemberOrigin &&
|
||||
containingClass == other.containingClass &&
|
||||
clsDelegate == other.clsDelegate
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = lightMemberOrigin?.hashCode() ?: 0
|
||||
result = 31 * result + clsDelegate.hashCode()
|
||||
result = 31 * result + containingClass.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
|
||||
|
||||
override fun getNavigationElement() = kotlinOrigin ?: super.getNavigationElement()
|
||||
@@ -111,6 +131,7 @@ sealed class KtLightFieldImpl(
|
||||
|
||||
override fun copy() = Factory.create(lightMemberOrigin?.copy(), clsDelegate, containingClass)
|
||||
|
||||
|
||||
class KtLightEnumConstant(
|
||||
origin: LightMemberOrigin?,
|
||||
override val clsDelegate: PsiEnumConstant,
|
||||
|
||||
@@ -182,4 +182,8 @@ fun accessorNameByPropertyName(name: String, accessor: KtLightMethod): String? {
|
||||
JvmAbi.isSetterName(methodName) -> JvmAbi.setterName(name)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun getAccessorNamesCandidatesByPropertyName(name: String): List<String> {
|
||||
return listOf(JvmAbi.setterName(name), JvmAbi.getterName(name))
|
||||
}
|
||||
Reference in New Issue
Block a user