[FIR IDE] LC Add callable declarations to KtFileSymbol

This commit is contained in:
Igor Yakovlev
2020-12-11 21:11:41 +03:00
parent fb63b74b37
commit da54dbba8e
3 changed files with 40 additions and 49 deletions
@@ -9,5 +9,8 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
abstract class KtFileSymbol : KtAnnotatedSymbol {
abstract val topLevelCallableSymbols: List<KtCallableSymbol>
abstract override fun createPointer(): KtSymbolPointer<KtFileSymbol>
}
@@ -12,31 +12,26 @@ import com.intellij.psi.impl.light.LightEmptyImplementsList
import com.intellij.psi.impl.light.LightModifierList
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.lazyPub
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.asJava.elements.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.asJava.classes.createField
import org.jetbrains.kotlin.idea.asJava.classes.createMethods
import org.jetbrains.kotlin.idea.frontend.api.analyze
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.psiUtil.isPrivate
class FirLightClassForFacade(
manager: PsiManager,
@@ -80,32 +75,24 @@ class FirLightClassForFacade(
override fun getModifierList(): PsiModifierList = _modifierList
override fun getScope(): PsiElement? = parent
private fun loadMethodsFromFile(
file: KtFile,
result: MutableList<KtLightMethod>
) {
val declarations = file.declarations
.filterIsInstance<KtNamedDeclaration>()
.filterNot { multiFileClass && it.isPrivate() }
if (declarations.isEmpty()) return
val symbols = analyze(file) {
declarations.mapNotNull {
it.getSymbol() as? KtCallableSymbol
}
}
createMethods(symbols.asSequence(), result, isTopLevel = true)
}
override fun getScope(): PsiElement = parent
private val _ownMethods: List<KtLightMethod> by lazyPub {
val result = mutableListOf<KtLightMethod>()
for (file in files) {
loadMethodsFromFile(file, result)
val methodsAndProperties = sequence<KtCallableSymbol> {
for (fileSymbol in fileSymbols) {
for (callableSymbol in fileSymbol.topLevelCallableSymbols) {
if (callableSymbol !is KtFunctionSymbol && callableSymbol !is KtPropertySymbol) continue
if (callableSymbol !is KtSymbolWithVisibility) continue
val isPrivate = callableSymbol.toPsiVisibilityForMember(isTopLevel = true) == PsiModifier.PRIVATE
if (isPrivate && multiFileClass) continue
yield(callableSymbol)
}
}
}
createMethods(methodsAndProperties, result, isTopLevel = true)
result
}
@@ -114,25 +101,16 @@ class FirLightClassForFacade(
}
private fun loadFieldsFromFile(
file: KtFile,
fileSymbol: KtFileSymbol,
nameGenerator: FirLightField.FieldNameGenerator,
result: MutableList<KtLightField>
) {
val properties = file.declarations
.filterIsInstance<KtProperty>()
.applyIf(multiFileClass) {
filter { it.hasModifier(KtTokens.CONST_KEYWORD) }
}
for (propertySymbol in fileSymbol.topLevelCallableSymbols) {
if (properties.isEmpty()) return
if (propertySymbol !is KtPropertySymbol) continue
val propertySymbols = analyze(file) {
properties.mapNotNull {
it.getSymbol() as? KtPropertySymbol
}
}
if (propertySymbol is KtKotlinPropertySymbol && propertySymbol.isConst && multiFileClass) continue
for (propertySymbol in propertySymbols) {
val isLateInitWithPublicAccessors = if (propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit) {
val getterIsPublic = propertySymbol.getter?.toPsiVisibilityForMember(isTopLevel = true)
?.let { it == PsiModifier.PUBLIC } ?: true
@@ -160,8 +138,8 @@ class FirLightClassForFacade(
private val _ownFields: List<KtLightField> by lazyPub {
val result = mutableListOf<KtLightField>()
val nameGenerator = FirLightField.FieldNameGenerator()
for (file in files) {
loadFieldsFromFile(file, nameGenerator, result)
for (fileSymbol in fileSymbols) {
loadFieldsFromFile(fileSymbol, nameGenerator, result)
}
result
}
@@ -266,6 +244,8 @@ class FirLightClassForFacade(
if (this.hashCode() != other.hashCode()) return false
if (manager != other.manager) return false
if (facadeClassFqName != other.facadeClassFqName) return false
if (!fileSymbols.containsAll(other.fileSymbols)) return false
if (!other.fileSymbols.containsAll(fileSymbols)) return false
return true
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.findPsi
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.convertAnnotation
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
@@ -27,7 +29,13 @@ internal class KtFirFileSymbol(
) : KtFileSymbol(), KtFirSymbol<FirFile> {
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.session) }
override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.session) }
override val topLevelCallableSymbols: List<KtCallableSymbol> by firRef.withFirAndCache {
it.declarations.mapNotNull { declaration ->
if (declaration is FirCallableDeclaration<*>) builder.buildCallableSymbol(declaration) else null
}
}
override fun createPointer(): KtSymbolPointer<KtFileSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }