[FIR IDE] LC Add KtFileSymbol and fix facade annotations

This commit is contained in:
Igor Yakovlev
2020-12-11 20:18:27 +03:00
parent 46071c1925
commit fb63b74b37
8 changed files with 91 additions and 13 deletions
@@ -121,6 +121,8 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali
fun KtPropertyAccessor.getPropertyAccessorSymbol(): KtPropertyAccessorSymbol = symbolProvider.getPropertyAccessorSymbol(this)
fun KtFile.getFileSymbol(): KtFileSymbol = symbolProvider.getFileSymbol(this)
/**
* @return symbol with specified [this@getClassOrObjectSymbolByClassId] or `null` in case such symbol is not found
*/
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.frontend.api.symbols
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 override fun createPointer(): KtSymbolPointer<KtFileSymbol>
}
@@ -30,6 +30,7 @@ abstract class KtSymbolProvider : KtAnalysisSessionComponent() {
}
abstract fun getParameterSymbol(psi: KtParameter): KtParameterSymbol
abstract fun getFileSymbol(psi: KtFile): KtFileSymbol
abstract fun getFunctionSymbol(psi: KtNamedFunction): KtFunctionSymbol
abstract fun getConstructorSymbol(psi: KtConstructor<*>): KtConstructorSymbol
abstract fun getTypeParameterSymbol(psi: KtTypeParameter): KtTypeParameterSymbol
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.mapAnnotationParameters
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFileSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSimpleConstantValue
@@ -24,6 +25,9 @@ import org.jetbrains.kotlin.psi.KtFile
internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation("kotlin/jvm/JvmSynthetic", annotationUseSiteTarget)
internal fun KtFileSymbol.hasJvmMultifileClassAnnotation(): Boolean =
hasAnnotation("kotlin/jvm/JvmMultifileClass", AnnotationUseSiteTarget.FILE)
internal fun KtAnnotatedSymbol.getJvmNameFromAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): String? {
val annotation = annotations.firstOrNull {
val siteTarget = it.useSiteTarget
@@ -120,11 +124,4 @@ internal fun KtAnnotatedSymbol.computeAnnotations(
}
return result
}
internal fun KtFile.hasJvmMultifileClassAnnotation(): Boolean = this.annotationEntries
.filter {
it.useSiteTarget?.getAnnotationUseSiteTarget() == AnnotationUseSiteTarget.FILE
}.any {
it.shortName?.asString() == "JvmMultifileClass"
}
}
@@ -20,6 +20,7 @@ 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.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.asJava.classes.createField
import org.jetbrains.kotlin.idea.asJava.classes.createMethods
@@ -51,14 +52,28 @@ class FirLightClassForFacade(
override val clsDelegate: PsiClass get() = invalidAccess()
private val fileSymbols by lazyPub {
files.map { ktFile ->
analyze(ktFile) {
ktFile.getFileSymbol()
}
}
}
private val _modifierList: PsiModifierList by lazyPub {
if (multiFileClass)
return@lazyPub LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
val modifiers = setOf(PsiModifier.PUBLIC, PsiModifier.FINAL)
//TODO make annotations for file site
val annotations: List<PsiAnnotation> = emptyList()
val annotations = fileSymbols.flatMap {
it.computeAnnotations(
this@FirLightClassForFacade,
NullabilityType.Unknown,
AnnotationUseSiteTarget.FILE,
includeAnnotationsWithoutSite = false
)
}
FirLightClassModifierList(this@FirLightClassForFacade, modifiers, annotations)
}
@@ -95,7 +110,7 @@ class FirLightClassForFacade(
}
private val multiFileClass: Boolean by lazyPub {
files.size > 1 || files.any { it.hasJvmMultifileClassAnnotation() }
files.size > 1 || fileSymbols.any { it.hasJvmMultifileClassAnnotation() }
}
private fun loadFieldsFromFile(
@@ -40,6 +40,7 @@ internal class KtSymbolByFirBuilder private constructor(
override val token: ValidityToken,
val withReadOnlyCaching: Boolean,
private val symbolsCache: BuilderCache<FirDeclaration, KtSymbol>,
private val filesCache: BuilderCache<FirFile, KtFileSymbol>,
private val typesCache: BuilderCache<ConeKotlinType, KtType>
) : ValidityTokenOwner {
private val resolveState by weakRef(resolveState)
@@ -56,7 +57,8 @@ internal class KtSymbolByFirBuilder private constructor(
resolveState = resolveState,
withReadOnlyCaching = false,
symbolsCache = BuilderCache(),
typesCache = BuilderCache()
typesCache = BuilderCache(),
filesCache = BuilderCache(),
)
@@ -68,7 +70,8 @@ internal class KtSymbolByFirBuilder private constructor(
resolveState = newResolveState,
withReadOnlyCaching = true,
symbolsCache = symbolsCache.createReadOnlyCopy(),
typesCache = typesCache.createReadOnlyCopy()
typesCache = typesCache.createReadOnlyCopy(),
filesCache = filesCache.createReadOnlyCopy(),
)
}
@@ -139,6 +142,8 @@ internal class KtSymbolByFirBuilder private constructor(
fun buildAnonymousFunctionSymbol(fir: FirAnonymousFunction) =
symbolsCache.cache(fir) { KtFirAnonymousFunctionSymbol(fir, resolveState, token, this) }
fun buildFileSymbol(fir: FirFile) = filesCache.cache(fir) { KtFirFileSymbol(fir, resolveState, token, this) }
fun buildVariableSymbol(fir: FirProperty): KtVariableSymbol = symbolsCache.cache(fir) {
when {
fir.isLocal -> KtFirLocalVariableSymbol(fir, resolveState, token, this)
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
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.KtFileSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
internal class KtFirFileSymbol(
fir: FirFile,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder
) : KtFileSymbol(), KtFirSymbol<FirFile> {
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.session) }
override fun createPointer(): KtSymbolPointer<KtFileSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating pointers for files from library is not supported yet")
}
override val annotations: List<KtAnnotationCall> by firRef.withFirAndCache(FirResolvePhase.TYPES) {
convertAnnotation(it)
}
}
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getFirFile
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirOfType
import org.jetbrains.kotlin.idea.fir.low.level.api.api.withFirDeclarationOfType
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
@@ -38,6 +39,10 @@ internal class KtFirSymbolProvider(
}
}
override fun getFileSymbol(psi: KtFile): KtFileSymbol = withValidityAssertion {
firSymbolBuilder.buildFileSymbol(psi.getFirFile(resolveState))
}
override fun getFunctionSymbol(psi: KtNamedFunction): KtFunctionSymbol = withValidityAssertion {
psi.withFirDeclarationOfType<FirSimpleFunction, KtFunctionSymbol>(resolveState) {
firSymbolBuilder.buildFunctionSymbol(it)