Light members: allow to get modifier list without computing delegate

This commit is contained in:
Pavel V. Talanov
2017-03-24 21:10:57 +03:00
parent e84a674504
commit c4be805962
3 changed files with 48 additions and 56 deletions
@@ -45,23 +45,13 @@ abstract class KtLightMemberImpl<out D : PsiMember>(
private val _modifierList by lazyPub { private val _modifierList by lazyPub {
if (lightMemberOrigin is LightMemberOriginForDeclaration) if (lightMemberOrigin is LightMemberOriginForDeclaration)
clsDelegate.modifierList?.let { KtLightModifierList(it, this) } KtLightModifierList(this, dummyDelegate?.modifierList)
else clsDelegate.modifierList else clsDelegate.modifierList!!
} }
override fun hasModifierProperty(name: String): Boolean { override fun hasModifierProperty(name: String) = _modifierList.hasModifierProperty(name)
if (dummyDelegate != null) {
if (name in visibilityModifiers) {
if (kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false) {
return clsDelegate.hasModifierProperty(name)
}
}
return dummyDelegate.hasModifierProperty(name)
}
return clsDelegate.hasModifierProperty(name)
}
override fun getModifierList(): PsiModifierList? = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
override fun toString(): String = "${this::class.java.simpleName}:$name" override fun toString(): String = "${this::class.java.simpleName}:$name"
@@ -105,3 +95,42 @@ internal fun getMemberOrigin(member: PsiMember): LightMemberOriginForDeclaration
return stubElement.getUserData<LightElementOrigin>(ORIGIN) as? LightMemberOriginForDeclaration ?: return null return stubElement.getUserData<LightElementOrigin>(ORIGIN) as? LightMemberOriginForDeclaration ?: return null
} }
class KtLightModifierList(
private val owner: KtLightMember<*>,
private val dummyDelegate: PsiModifierList?
) : LightElement(owner.manager, KotlinLanguage.INSTANCE), PsiModifierList {
private val clsDelegate by lazyPub { owner.clsDelegate.modifierList!! }
private val _annotations by lazyPub { computeAnnotations(this, clsDelegate) }
override fun hasModifierProperty(name: String): Boolean {
if (dummyDelegate != null) {
if (name in visibilityModifiers) {
if (owner.kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false) {
return clsDelegate.hasModifierProperty(name)
}
}
return dummyDelegate.hasModifierProperty(name)
}
return clsDelegate.hasModifierProperty(name)
}
override fun hasExplicitModifier(name: String) = hasModifierProperty(name)
override fun setModifierProperty(name: String, value: Boolean) = clsDelegate.setModifierProperty(name, value)
override fun checkSetModifierProperty(name: String, value: Boolean) = clsDelegate.checkSetModifierProperty(name, value)
override fun addAnnotation(qualifiedName: String) = clsDelegate.addAnnotation(qualifiedName)
override fun getApplicableAnnotations(): Array<out PsiAnnotation> = annotations
override fun getAnnotations(): Array<out PsiAnnotation> = _annotations.value
override fun findAnnotation(qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
override fun getParent() = owner
override fun getText(): String? = ""
override fun getTextRange() = TextRange.EMPTY_RANGE
override fun copy(): PsiElement = KtLightModifierList(owner, dummyDelegate)
override fun getReferences() = PsiReference.EMPTY_ARRAY
override fun isEquivalentTo(another: PsiElement?) =
another is KtLightModifierList && owner == another.owner
override fun toString() = "Light modifier list of $owner"
}
@@ -16,14 +16,14 @@
package org.jetbrains.kotlin.asJava.elements package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiAnnotation
import com.intellij.psi.* import com.intellij.psi.PsiAnnotationOwner
import com.intellij.psi.PsiModifierList
import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.ArrayUtil
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.classes.lazyPub
@@ -54,43 +54,6 @@ abstract class KtLightModifierListWithExplicitModifiers(
override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName) override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName)
} }
class KtLightModifierList(
private val delegate: PsiModifierList,
private val owner: PsiModifierListOwner
) : PsiModifierList by delegate {
private val _annotations by lazyPub { computeAnnotations(this, delegate) }
override fun getAnnotations(): Array<out PsiAnnotation> = _annotations.value
override fun findAnnotation(@NonNls qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName)
override fun getParent() = owner
override fun getText(): String? = ""
override fun getLanguage() = KotlinLanguage.INSTANCE
override fun getTextRange() = TextRange.EMPTY_RANGE
override fun getStartOffsetInParent() = -1
override fun getTextLength() = 0
override fun getPrevSibling(): PsiElement? = null
override fun getNextSibling(): PsiElement? = null
override fun findElementAt(offset: Int): PsiElement? = null
override fun findReferenceAt(offset: Int): PsiReference? = null
override fun getTextOffset() = -1
override fun isWritable() = false
override fun isPhysical() = false
override fun textToCharArray(): CharArray = ArrayUtil.EMPTY_CHAR_ARRAY;
override fun textMatches(text: CharSequence): Boolean = getText() == text.toString()
override fun textMatches(element: PsiElement): Boolean = text == element.text
override fun textContains(c: Char): Boolean = text?.contains(c) ?: false
override fun copy(): PsiElement = KtLightModifierList(delegate, owner)
override fun getReferences() = PsiReference.EMPTY_ARRAY
override fun isEquivalentTo(another: PsiElement?) =
another is KtLightModifierList && delegate == another.delegate && owner == another.owner
}
internal fun computeAnnotations(lightElement: PsiModifierList, internal fun computeAnnotations(lightElement: PsiModifierList,
delegate: PsiAnnotationOwner): CachedValue<Array<out PsiAnnotation>> { delegate: PsiAnnotationOwner): CachedValue<Array<out PsiAnnotation>> {
fun doCompute(): Array<PsiAnnotation> { fun doCompute(): Array<PsiAnnotation> {
@@ -217,7 +217,7 @@ object LightClassLazinessChecker {
private fun fieldInfo(field: PsiField) = with(field) { private fun fieldInfo(field: PsiField) = with(field) {
FieldInfo( FieldInfo(
name!!, PsiModifier.MODIFIERS.asList().filter { hasModifierProperty(it) } name!!, PsiModifier.MODIFIERS.asList().filter { modifierList!!.hasModifierProperty(it) }
) )
} }
@@ -230,7 +230,7 @@ object LightClassLazinessChecker {
private fun methodInfo(method: PsiMethod) = with(method) { private fun methodInfo(method: PsiMethod) = with(method) {
MethodInfo( MethodInfo(
name, PsiModifier.MODIFIERS.asList().filter { hasModifierProperty(it) }, name, PsiModifier.MODIFIERS.asList().filter { modifierList.hasModifierProperty(it) },
isConstructor, method.parameterList.parametersCount isConstructor, method.parameterList.parametersCount
) )
} }