Light classes in IDE: Make light class delegate construction a two step process
Step 0: Light class object is created, no delegates are computed Step 1: constructs dummy delegate which can not be relied upon to know signature of any member It can be used to construct light field and light method objects (which can correctly respond to some queries) before constructing real delegate Step 2: Construct real delegate if dummy delegate is not enough to respond to a query This speeds up multiple scenarios where getMethods() and getFields() are called on numerous classes Dummy delegate's faster consruction is achieved by using specially setup dumb analysis instead of ide analysis Introduce LazyLightClassDataHolder: which manages creation of Step 1 and Step 2 delegates Introduce MemberIndex: keeping track of member creation order, helps matching light class delegates created in different contexts KtLightMethod and Field: make use of dummy delegate KtLightMethod no longer extends LightMethod since it requires eager delegate construction KtLightMethod now implements PsiAnnotationMethod for convenience (ClsMethodImpl implements PsiAnnotationMethod)
This commit is contained in:
@@ -20,7 +20,10 @@ import com.intellij.psi.PsiCodeBlock
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.elements.isGetter
|
||||
import org.jetbrains.kotlin.asJava.elements.isSetter
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.uast.*
|
||||
@@ -30,9 +33,15 @@ import org.jetbrains.uast.kotlin.*
|
||||
open class KotlinUMethod(
|
||||
psi: KtLightMethod,
|
||||
override val uastParent: UElement?
|
||||
) : UMethod, JavaUElementWithComments, PsiMethod by psi {
|
||||
) : UAnnotationMethod, JavaUElementWithComments, PsiMethod by psi {
|
||||
override val psi: KtLightMethod = unwrap<UMethod, KtLightMethod>(psi)
|
||||
|
||||
override val uastDefaultValue by lz {
|
||||
val annotationParameter = psi.kotlinOrigin as? KtParameter ?: return@lz null
|
||||
val defaultValue = annotationParameter.defaultValue ?: return@lz null
|
||||
getLanguagePlugin().convertElement(defaultValue, this) as? UExpression
|
||||
}
|
||||
|
||||
private val kotlinOrigin = (psi.originalElement as KtLightElement<*, *>).kotlinOrigin
|
||||
|
||||
override val annotations by lz {
|
||||
@@ -73,20 +82,6 @@ open class KotlinUMethod(
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
companion object {
|
||||
fun create(psi: KtLightMethod, containingElement: UElement?) = when (psi) {
|
||||
is KtLightMethodImpl.KtLightAnnotationMethod -> KotlinUAnnotationMethod(psi, containingElement)
|
||||
else -> KotlinUMethod(psi, containingElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinUAnnotationMethod(
|
||||
override val psi: KtLightMethodImpl.KtLightAnnotationMethod,
|
||||
containingElement: UElement?
|
||||
) : KotlinUMethod(psi, containingElement), UAnnotationMethod {
|
||||
override val uastDefaultValue by lz {
|
||||
val annotationParameter = psi.kotlinOrigin as? KtParameter ?: return@lz null
|
||||
val defaultValue = annotationParameter.defaultValue ?: return@lz null
|
||||
getLanguagePlugin().convertElement(defaultValue, this) as? UExpression
|
||||
fun create(psi: KtLightMethod, containingElement: UElement?) = KotlinUMethod(psi, containingElement)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -6,4 +6,4 @@ class Foo {
|
||||
val x = Foo::bar
|
||||
|
||||
// REF:Foo::bar
|
||||
// RESULT:KtLightAnnotationMethod:bar
|
||||
// RESULT:KtLightMethodImpl:bar
|
||||
|
||||
@@ -14,7 +14,7 @@ UFile (package = ) [public abstract interface Callback {...]
|
||||
UCallExpression (kind = UastCallKind(name='constructor_call'), argCount = 0)) [<init>()] : PsiType:UnsupportedOperationException
|
||||
UIdentifier (Identifier (UnsupportedOperationException)) [UIdentifier (Identifier (UnsupportedOperationException))]
|
||||
USimpleNameReferenceExpression (identifier = <init>) [<init>] : PsiType:UnsupportedOperationException
|
||||
UMethod (name = Model) [public fun Model() {...}]
|
||||
UAnnotationMethod (name = Model) [public fun Model() {...}]
|
||||
UBlockExpression [{...}]
|
||||
UBlockExpression [{...}] : PsiType:Unit
|
||||
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [crashMe(Callback.java, { ...})] : PsiType:Unit
|
||||
|
||||
Reference in New Issue
Block a user