From c4be805962109d5dd1ff1c78dbd0d89861a89c14 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Fri, 24 Mar 2017 21:10:57 +0300 Subject: [PATCH] Light members: allow to get modifier list without computing delegate --- .../asJava/elements/KtLightMemberImpl.kt | 57 ++++++++++++++----- ...tLightModifierListWithExplicitModifiers.kt | 43 +------------- .../resolve/AbstractIdeLightClassTest.kt | 4 +- 3 files changed, 48 insertions(+), 56 deletions(-) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMemberImpl.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMemberImpl.kt index e610c728ad5..c30d421521b 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMemberImpl.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMemberImpl.kt @@ -45,23 +45,13 @@ abstract class KtLightMemberImpl( private val _modifierList by lazyPub { if (lightMemberOrigin is LightMemberOriginForDeclaration) - clsDelegate.modifierList?.let { KtLightModifierList(it, this) } - else clsDelegate.modifierList + KtLightModifierList(this, dummyDelegate?.modifierList) + else clsDelegate.modifierList!! } - override fun hasModifierProperty(name: String): Boolean { - 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 hasModifierProperty(name: String) = _modifierList.hasModifierProperty(name) - override fun getModifierList(): PsiModifierList? = _modifierList + override fun getModifierList(): PsiModifierList = _modifierList override fun toString(): String = "${this::class.java.simpleName}:$name" @@ -105,3 +95,42 @@ internal fun getMemberOrigin(member: PsiMember): LightMemberOriginForDeclaration return stubElement.getUserData(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 = annotations + override fun getAnnotations(): Array = _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" +} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierListWithExplicitModifiers.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierListWithExplicitModifiers.kt index 7d1634b4035..8dc54eef222 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierListWithExplicitModifiers.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightModifierListWithExplicitModifiers.kt @@ -16,14 +16,14 @@ package org.jetbrains.kotlin.asJava.elements -import com.intellij.openapi.util.TextRange -import com.intellij.psi.* +import com.intellij.psi.PsiAnnotation +import com.intellij.psi.PsiAnnotationOwner +import com.intellij.psi.PsiModifierList import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker -import com.intellij.util.ArrayUtil import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.classes.lazyPub @@ -54,43 +54,6 @@ abstract class KtLightModifierListWithExplicitModifiers( 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 = _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, delegate: PsiAnnotationOwner): CachedValue> { fun doCompute(): Array { diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/AbstractIdeLightClassTest.kt b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/AbstractIdeLightClassTest.kt index f4bf3d8d7c8..5d449d5000e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/AbstractIdeLightClassTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/AbstractIdeLightClassTest.kt @@ -217,7 +217,7 @@ object LightClassLazinessChecker { private fun fieldInfo(field: PsiField) = with(field) { 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) { MethodInfo( - name, PsiModifier.MODIFIERS.asList().filter { hasModifierProperty(it) }, + name, PsiModifier.MODIFIERS.asList().filter { modifierList.hasModifierProperty(it) }, isConstructor, method.parameterList.parametersCount ) }