[lc] extract common code to KtLightClassForFacadeBase

^KT-53543
This commit is contained in:
Dmitry Gridin
2022-08-10 17:30:59 +02:00
committed by Space
parent acfbe30f7c
commit 5be31e575c
2 changed files with 54 additions and 48 deletions
@@ -12,12 +12,15 @@ import com.intellij.psi.impl.light.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.impl.light.LightModifierList
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.JvmNames
import org.jetbrains.kotlin.name.JvmNames.JVM_NAME_SHORT import org.jetbrains.kotlin.name.JvmNames.JVM_NAME_SHORT
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -28,15 +31,25 @@ import javax.swing.Icon
abstract class KtLightClassForFacadeBase constructor( abstract class KtLightClassForFacadeBase constructor(
override val facadeClassFqName: FqName, override val facadeClassFqName: FqName,
override val files: Collection<KtFile> final override val files: Collection<KtFile>
) : KtLightClassBase(files.first().manager), KtLightClassForFacade { ) : KtLightClassBase(files.first().manager), KtLightClassForFacade {
private val firstFileInFacade by lazyPub { files.iterator().next() } private val firstFileInFacade by lazyPub { files.first() }
private val modifierList: PsiModifierList = val isMultiFileClass: Boolean by lazyPub {
LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL) files.size > 1 || JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(firstFileInFacade, JvmNames.JVM_MULTIFILE_CLASS_SHORT) != null
}
private val implementsList: LightEmptyImplementsList = private val _modifierList: PsiModifierList by lazyPub {
if (isMultiFileClass)
LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
else
createModifierListForSimpleFacade()
}
private val _implementsList: LightEmptyImplementsList by lazyPub {
LightEmptyImplementsList(manager) LightEmptyImplementsList(manager)
}
private val packageClsFile by lazyPub { private val packageClsFile by lazyPub {
FakeFileForLightClass( FakeFileForLightClass(
@@ -46,6 +59,19 @@ abstract class KtLightClassForFacadeBase constructor(
) )
} }
private val _ownMethods: List<KtLightMethod> by lazyPub {
createOwnMethods()
}
private val _ownFields: List<KtLightField> by lazyPub {
createOwnFields()
}
abstract fun createOwnMethods(): List<KtLightMethod>
abstract fun createOwnFields(): List<KtLightField>
abstract fun createModifierListForSimpleFacade(): PsiModifierList
override fun getParent(): PsiElement = containingFile override fun getParent(): PsiElement = containingFile
override val kotlinOrigin: KtClassOrObject? get() = null override val kotlinOrigin: KtClassOrObject? get() = null
@@ -53,7 +79,7 @@ abstract class KtLightClassForFacadeBase constructor(
val fqName: FqName val fqName: FqName
get() = facadeClassFqName get() = facadeClassFqName
override fun getModifierList() = modifierList override fun getModifierList() = _modifierList
override fun hasModifierProperty(@NonNls name: String) = modifierList.hasModifierProperty(name) override fun hasModifierProperty(@NonNls name: String) = modifierList.hasModifierProperty(name)
@@ -79,7 +105,7 @@ abstract class KtLightClassForFacadeBase constructor(
override fun getDocComment(): Nothing? = null override fun getDocComment(): Nothing? = null
override fun getImplementsList() = implementsList override fun getImplementsList() = _implementsList
override fun getImplementsListTypes(): Array<out PsiClassType> = PsiClassType.EMPTY_ARRAY override fun getImplementsListTypes(): Array<out PsiClassType> = PsiClassType.EMPTY_ARRAY
@@ -204,5 +230,9 @@ abstract class KtLightClassForFacadeBase constructor(
override fun isWritable() = files.all { it.isWritable } override fun isWritable() = files.all { it.isWritable }
override fun getOwnFields() = _ownFields
override fun getOwnMethods() = _ownMethods
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this) override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this)
} }
@@ -8,14 +8,9 @@ package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiModifier import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList import com.intellij.psi.PsiModifierList
import com.intellij.psi.impl.light.LightModifierList
import org.jetbrains.kotlin.asJava.elements.* import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil.findAnnotationEntryOnFileNoResolve
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.JvmNames.JVM_MULTIFILE_CLASS
import org.jetbrains.kotlin.name.JvmNames.JVM_MULTIFILE_CLASS_SHORT
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
@@ -24,17 +19,10 @@ import org.jetbrains.kotlin.psi.psiUtil.isPrivate
class KtUltraLightClassForFacade( class KtUltraLightClassForFacade(
facadeClassFqName: FqName, facadeClassFqName: FqName,
files: Collection<KtFile>, files: Collection<KtFile>,
private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>> private val filesWithSupports: Collection<Pair<KtFile, KtUltraLightSupport>>,
) : KtLightClassForFacadeBase(facadeClassFqName, files) { ) : KtLightClassForFacadeBase(facadeClassFqName, files) {
private val _modifierList: PsiModifierList by lazyPub { private val _modifierListForSimpleFacade: PsiModifierList by lazyPub {
if (isMultiFileClass) KtUltraLightSimpleModifierList(owner = this, modifiers = setOf(PsiModifier.PUBLIC, PsiModifier.FINAL))
LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
else
KtUltraLightSimpleModifierList(owner = this, modifiers = setOf(PsiModifier.PUBLIC, PsiModifier.FINAL))
}
private val isMultiFileClass: Boolean by lazyPub {
files.size > 1 || files.any { findAnnotationEntryOnFileNoResolve(it, JVM_MULTIFILE_CLASS_SHORT) != null }
} }
private val _givenAnnotations: List<KtLightAbstractAnnotation>? by lazyPub { private val _givenAnnotations: List<KtLightAbstractAnnotation>? by lazyPub {
@@ -44,7 +32,7 @@ class KtUltraLightClassForFacade(
name = entry.shortName?.identifier, name = entry.shortName?.identifier,
lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() }, lazyQualifiedName = { entry.analyzeAnnotation()?.fqName?.asString() },
kotlinOrigin = entry, kotlinOrigin = entry,
parent = _modifierList parent = modifierList
) )
} }
} }
@@ -53,7 +41,7 @@ class KtUltraLightClassForFacade(
override val givenAnnotations: List<KtLightAbstractAnnotation>? override val givenAnnotations: List<KtLightAbstractAnnotation>?
get() = if (isMultiFileClass) emptyList() else _givenAnnotations get() = if (isMultiFileClass) emptyList() else _givenAnnotations
override fun getModifierList(): PsiModifierList = _modifierList override fun createModifierListForSimpleFacade(): PsiModifierList = _modifierListForSimpleFacade
override fun getScope(): PsiElement? = parent override fun getScope(): PsiElement? = parent
@@ -103,35 +91,23 @@ class KtUltraLightClassForFacade(
} }
} }
private val _ownMethods: List<KtLightMethod> by lazyPub { override fun createOwnFields(): List<KtLightField> = hashSetOf<String>().let { nameCache ->
val result = mutableListOf<KtLightMethod>() filesWithSupportsWithCreators.flatMap { (file, _, creator) ->
for ((file, support, creator) in filesWithSupportsWithCreators) { val allProperties = file.declarations.filterIsInstance<KtProperty>()
loadMethodsFromFile(file, support, creator, result) val properties = if (isMultiFileClass) allProperties.filter { it.hasModifier(KtTokens.CONST_KEYWORD) } else allProperties
} properties.mapNotNull {
if (!multiFileClass) result else result.filterNot { it.hasModifierProperty(PsiModifier.PRIVATE) } creator.createPropertyField(it, nameCache, forceStatic = true)
}
private val multiFileClass: Boolean by lazyPub {
filesWithSupports.any {
it.second.findAnnotation(it.first, JVM_MULTIFILE_CLASS) != null
}
}
private val _ownFields: List<KtLightField> by lazyPub {
hashSetOf<String>().let { nameCache ->
filesWithSupportsWithCreators.flatMap { (file, _, creator) ->
val allProperties = file.declarations.filterIsInstance<KtProperty>()
val properties = if (multiFileClass) allProperties.filter { it.hasModifier(KtTokens.CONST_KEYWORD) } else allProperties
properties.mapNotNull {
creator.createPropertyField(it, nameCache, forceStatic = true)
}
} }
} }
} }
override fun getOwnFields() = _ownFields override fun createOwnMethods() = mutableListOf<KtLightMethod>().let { result ->
for ((file, support, creator) in filesWithSupportsWithCreators) {
loadMethodsFromFile(file, support, creator, result)
}
override fun getOwnMethods() = _ownMethods if (!isMultiFileClass) result else result.filterNot { it.hasModifierProperty(PsiModifier.PRIVATE) }
}
override fun copy(): KtLightClassForFacade = KtUltraLightClassForFacade(facadeClassFqName, files, filesWithSupports) override fun copy(): KtLightClassForFacade = KtUltraLightClassForFacade(facadeClassFqName, files, filesWithSupports)
} }