FIR IDE: Implement symbol restoring for member symbols

This commit is contained in:
Ilya Kirillov
2020-08-11 20:46:41 +03:00
parent e4995175a4
commit c8ab0766c9
67 changed files with 1136 additions and 253 deletions
@@ -45,7 +45,6 @@ import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractCodeInsightActionT
import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractGenerateHashCodeAndEqualsActionTest
import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractGenerateTestSupportMethodActionTest
import org.jetbrains.kotlin.idea.codeInsight.generate.AbstractGenerateToStringActionTest
import org.jetbrains.kotlin.idea.codeInsight.hints.AbstractKotlinLambdasHintsProvider
import org.jetbrains.kotlin.idea.codeInsight.hints.AbstractKotlinReferenceTypeHintsProviderTest
import org.jetbrains.kotlin.idea.codeInsight.moveUpDown.AbstractMoveLeftRightTest
import org.jetbrains.kotlin.idea.codeInsight.moveUpDown.AbstractMoveStatementTest
@@ -91,8 +90,9 @@ import org.jetbrains.kotlin.idea.fir.AbstractKtDeclarationAndFirDeclarationEqual
import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest
import org.jetbrains.kotlin.idea.frontend.api.fir.AbstractResolveCallTest
import org.jetbrains.kotlin.idea.frontend.api.scopes.AbstractMemberScopeByFqNameTest
import org.jetbrains.kotlin.idea.frontend.api.symbols.AbstractSymbolFromLibraryPointerRestoreTest
import org.jetbrains.kotlin.idea.frontend.api.symbols.AbstractSymbolsByFqNameBuildingTest
import org.jetbrains.kotlin.idea.frontend.api.symbols.AbstractSymbolPointerTest
import org.jetbrains.kotlin.idea.frontend.api.symbols.AbstractSymbolFromSourcePointerRestoreTest
import org.jetbrains.kotlin.idea.frontend.api.symbols.AbstractSymbolsByPsiBuildingTest
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
@@ -970,9 +970,13 @@ fun main(args: Array<String>) {
model("memberScopeByFqName", extension = "txt")
}
testClass<AbstractSymbolPointerTest> {
testClass<AbstractSymbolFromSourcePointerRestoreTest> {
model("symbolPointer", extension = "kt")
}
testClass<AbstractSymbolFromLibraryPointerRestoreTest> {
model("resoreSymbolFromLibrary", extension = "txt")
}
}
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", "idea/testData") {
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.frontend.api.scopes.KtScopeProvider
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeRenderer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.*
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import java.lang.reflect.InvocationTargetException
import kotlin.reflect.KProperty
import kotlin.reflect.jvm.javaGetter
@@ -18,7 +19,12 @@ object DebugSymbolRenderer {
appendLine("${klass.simpleName}:")
klass.members.filterIsInstance<KProperty<*>>().sortedBy { it.name }.forEach { property ->
if (property.name in ignoredPropertyNames) return@forEach
val value = property.javaGetter?.invoke(symbol) ?: return@forEach
val getter = property.javaGetter ?: return@forEach
val value = try {
getter.invoke(symbol)
} catch (e: InvocationTargetException) {
"Could not render due to ${e.cause}"
}
val stringValue = renderValue(value)
appendLine(" ${property.name}: $stringValue")
}
@@ -26,6 +32,7 @@ object DebugSymbolRenderer {
private fun renderValue(value: Any?): String = when (value) {
null -> "null"
is String -> value
is Boolean -> value.toString()
is Name -> value.asString()
is FqName -> value.asString()
@@ -5,4 +5,8 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
abstract class KtCallableSymbol : KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
abstract class KtCallableSymbol : KtSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtCallableSymbol>
}
@@ -5,15 +5,18 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
abstract class KtClassLikeSymbol : KtSymbol, KtNamedSymbol, KtSymbolWithKind {
abstract val classId: ClassId
abstract override fun createPointer(): KtSymbolPointer<KtClassLikeSymbol>
}
abstract class KtTypeAliasSymbol : KtClassLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.TOP_LEVEL
abstract override fun createPointer(): KtSymbolPointer<KtTypeAliasSymbol>
}
abstract class KtClassOrObjectSymbol : KtClassLikeSymbol(), KtSymbolWithTypeParameters, KtSymbolWithModality<KtSymbolModality> {
@@ -5,15 +5,20 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
sealed class KtFunctionLikeSymbol : KtCallableSymbol(), KtTypedSymbol, KtSymbolWithKind {
abstract val valueParameters: List<KtParameterSymbol>
abstract override fun createPointer(): KtSymbolPointer<KtFunctionLikeSymbol>
}
abstract class KtAnonymousFunctionSymbol : KtFunctionLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
abstract override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol>
}
abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
@@ -27,6 +32,8 @@ abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
abstract val fqName: FqName?
abstract override val valueParameters: List<KtFunctionParameterSymbol>
abstract override fun createPointer(): KtSymbolPointer<KtFunctionSymbol>
}
abstract class KtConstructorSymbol : KtFunctionLikeSymbol() {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.FqName
abstract class KtPackageSymbol : KtSymbol {
@@ -7,12 +7,13 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
interface KtSymbol : ValidityTokenOwner {
val origin: KtSymbolOrigin
val psi: PsiElement?
fun createPointer(): KtSymbolPointer<KtSymbol> = NonRestorableKtSymbolPointer
fun createPointer(): KtSymbolPointer<KtSymbol>
}
enum class KtSymbolOrigin {
@@ -5,6 +5,10 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
abstract class KtTypeParameterSymbol : KtSymbol, KtNamedSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
abstract class KtTypeParameterSymbol : KtSymbol, KtNamedSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtTypeParameterSymbol>
}
@@ -5,39 +5,54 @@
package org.jetbrains.kotlin.idea.frontend.api.symbols
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
abstract class KtVariableLikeSymbol : KtCallableSymbol(), KtTypedSymbol, KtNamedSymbol, KtSymbolWithKind
abstract class KtVariableLikeSymbol : KtCallableSymbol(), KtTypedSymbol, KtNamedSymbol, KtSymbolWithKind {
abstract override fun createPointer(): KtSymbolPointer<KtVariableLikeSymbol>
}
abstract class KtEnumEntrySymbol : KtVariableLikeSymbol() {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
abstract val enumClassId: ClassId
abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol>
}
abstract class KtParameterSymbol : KtVariableLikeSymbol() {
abstract val hasDefaultValue: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtParameterSymbol>
}
abstract class KtVariableSymbol : KtVariableLikeSymbol() {
abstract val isVal: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtVariableSymbol>
}
abstract class KtJavaFieldSymbol : KtVariableSymbol(), KtSymbolWithModality<KtCommonSymbolModality> {
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
abstract override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol>
}
// TODO getters & setters
abstract class KtPropertySymbol : KtVariableSymbol(), KtPossibleExtensionSymbol, KtSymbolWithModality<KtCommonSymbolModality> {
abstract val fqName: FqName
abstract override fun createPointer(): KtSymbolPointer<KtPropertySymbol>
}
abstract class KtLocalVariableSymbol : KtVariableSymbol()
abstract class KtLocalVariableSymbol : KtVariableSymbol() {
abstract override fun createPointer(): KtSymbolPointer<KtLocalVariableSymbol>
}
abstract class KtFunctionParameterSymbol : KtParameterSymbol() {
abstract val isVararg: Boolean
abstract override fun createPointer(): KtSymbolPointer<KtFunctionParameterSymbol>
}
abstract class KtConstructorParameterSymbol : KtParameterSymbol(), KtNamedSymbol {
abstract val constructorParameterKind: KtConstructorParameterSymbolKind
abstract override fun createPointer(): KtSymbolPointer<KtConstructorParameterSymbol>
}
enum class KtConstructorParameterSymbolKind {
@@ -0,0 +1,9 @@
/*
* 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.pointers
class CanNotCreateSymbolPointerForLocalLibraryDeclarationException(description: String) :
IllegalStateException("Could not create a symbol pointer for local symbol $description")
@@ -0,0 +1,30 @@
/*
* 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.pointers
import com.intellij.psi.SmartPsiElementPointer
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
class KtPsiBasedSymbolPointer<S : KtSymbol>(private val psiPointer: SmartPsiElementPointer<out KtDeclaration>) : KtSymbolPointer<S>() {
override fun restoreSymbol(analysisSession: KtAnalysisSession): S? {
val psi = psiPointer.element ?: return null
@Suppress("UNCHECKED_CAST")
return analysisSession.symbolProvider.getSymbol(psi) as S?
}
companion object {
fun <S : KtSymbol> createForSymbolFromSource(symbol: S): KtPsiBasedSymbolPointer<S>? {
if (symbol.origin == KtSymbolOrigin.LIBRARY) return null
val psi = symbol.psi as? KtDeclaration ?: return null
return KtPsiBasedSymbolPointer(psi.createSmartPointer())
}
}
}
@@ -3,33 +3,33 @@
* 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
package org.jetbrains.kotlin.idea.frontend.api.symbols.pointers
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
/**
* `KtSymbol` is valid only during read action it was created in
* To pass the symbol from one read action to another the KtSymbolPointer should be used
*
* We can restore the symbol
* * for function & property symbol if its signature was not changed
* * for local variable symbol if code block it was declared in was not changed
* * for class & type alias symbols if its qualified name was not changed
* * for package symbol if the package is still exists
* * for symbol which came from Kotlin source it will be restored based on [com.intellij.psi.SmartPsiElementPointer]
* * restoring symbols which came from Java source is not supported yet
* * for library symbols:
* * for function & property symbol if its signature was not changed
* * for local variable symbol if code block it was declared in was not changed
* * for class & type alias symbols if its qualified name was not changed
* * for package symbol if the package is still exists
*
* @see org.jetbrains.kotlin.idea.frontend.api.ReadActionConfinementValidityToken
*/
interface KtSymbolPointer<out S : KtSymbol> {
abstract class KtSymbolPointer<out S : KtSymbol> {
/**
* @return restored symbol (possibly the new symbol instance) if one is still valid, `null` otherwise
*/
fun restoreSymbol(analysisSession: KtAnalysisSession): S?
abstract fun restoreSymbol(analysisSession: KtAnalysisSession): S?
}
object NonRestorableKtSymbolPointer : KtSymbolPointer<Nothing> {
override fun restoreSymbol(analysisSession: KtAnalysisSession): Nothing? = null
}
inline fun <S : KtSymbol> symbolPointer(crossinline getSymbol: (KtAnalysisSession) -> S?) = object : KtSymbolPointer<S> {
inline fun <S : KtSymbol> symbolPointer(crossinline getSymbol: (KtAnalysisSession) -> S?) = object : KtSymbolPointer<S>() {
override fun restoreSymbol(analysisSession: KtAnalysisSession): S? = getSymbol(analysisSession)
}
+1
View File
@@ -9,6 +9,7 @@ dependencies {
compile(project(":idea:idea-frontend-api"))
compile(project(":idea:idea-core"))
compile(project(":compiler:fir:fir2ir"))
compile(project(":compiler:ir.tree"))
compile(project(":compiler:fir:resolve"))
compile(project(":compiler:fir:checkers"))
compile(project(":compiler:fir:java"))
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.fir.low.level.api
import com.intellij.openapi.module.impl.scopes.ModuleWithDependentsScope
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.registerCheckersComponent
@@ -16,6 +15,7 @@ import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.registerExtensions
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.resolve.calls.jvm.registerJvmCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -48,6 +48,7 @@ internal class FirIdeJavaModuleBasedSession private constructor(
moduleInfo: ModuleSourceInfo,
firPhaseRunner: FirPhaseRunner,
sessionProvider: FirSessionProvider,
librariesSession: FirIdeModuleLibraryDependenciesSession,
): FirIdeJavaModuleBasedSession {
val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
val firBuilder = FirFileBuilder(sessionProvider as FirIdeSessionProvider, scopeProvider, firPhaseRunner)
@@ -83,7 +84,7 @@ internal class FirIdeJavaModuleBasedSession private constructor(
buildList {
add(provider)
add(JavaSymbolProvider(this@apply, sessionProvider.project, searchScope))
add(FirIdeModuleLibraryDependenciesSession.create(moduleInfo, sessionProvider, project).firSymbolProvider)
add(librariesSession.firSymbolProvider)
}
) as FirSymbolProvider
)
@@ -10,6 +10,7 @@ import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.util.psiModificationTrackerBasedCachedValue
import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.idea.caches.project.*
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeModuleLibraryDependenciesSession
internal class FirIdeResolveStateService(private val project: Project) {
private val stateCache by psiModificationTrackerBasedCachedValue(project) {
@@ -19,14 +20,26 @@ internal class FirIdeResolveStateService(private val project: Project) {
private fun createResolveStateFor(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl {
val sessionProvider = FirIdeSessionProvider(project)
val firPhaseRunner = FirPhaseRunner()
val session = FirIdeJavaModuleBasedSession.create(
val librariesSession = FirIdeModuleLibraryDependenciesSession.create(moduleInfo as ModuleSourceInfo, sessionProvider, project)
val sourcesSession = FirIdeJavaModuleBasedSession.create(
project,
moduleInfo as ModuleSourceInfo,
moduleInfo,
firPhaseRunner,
sessionProvider,
librariesSession,
).apply { sessionProvider.registerSession(moduleInfo, this) }
return FirModuleResolveStateImpl(moduleInfo, session, sessionProvider, session.firFileBuilder, session.cache)
return FirModuleResolveStateImpl(
moduleInfo,
sourcesSession,
librariesSession,
sessionProvider,
sourcesSession.firFileBuilder,
sourcesSession.cache
)
}
fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl =
@@ -27,7 +27,8 @@ import org.jetbrains.kotlin.psi.KtFile
abstract class FirModuleResolveState {
abstract val moduleInfo: IdeaModuleInfo
abstract val firSession: FirSession
abstract val firIdeSourcesSession: FirSession
abstract val firIdeLibrariesSession: FirSession
abstract fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession
@@ -57,7 +58,8 @@ abstract class FirModuleResolveState {
internal open class FirModuleResolveStateImpl(
override val moduleInfo: IdeaModuleInfo,
override val firSession: FirSession,
override val firIdeSourcesSession: FirSession,
override val firIdeLibrariesSession: FirSession,
private val sessionProvider: FirIdeSessionProvider,
val firFileBuilder: FirFileBuilder,
val fileCache: ModuleFileCache,
@@ -24,7 +24,8 @@ internal class FirModuleResolveStateForCompletion(
private val originalState: FirModuleResolveStateImpl
) : FirModuleResolveState() {
override val moduleInfo: IdeaModuleInfo get() = originalState.moduleInfo
override val firSession: FirSession get() = originalState.firSession
override val firIdeSourcesSession: FirSession get() = originalState.firIdeSourcesSession
override val firIdeLibrariesSession: FirSession get() = originalState.firIdeSourcesSession
private val psiToFirCache = PsiToFirCache(originalState.fileCache)
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.caches.resolve.IDEPackagePartProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.IdeSessionComponents
import org.jetbrains.kotlin.idea.search.minus
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
@@ -47,7 +48,7 @@ class FirIdeModuleLibraryDependenciesSession private constructor(
val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, searchScope)
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
register(
FirSymbolProvider::class,
FirCompositeSymbolProvider(
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.fir
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
@@ -69,13 +70,19 @@ internal fun FirReference.getResolvedKtSymbolOfNameReference(builder: KtSymbolBy
builder.buildSymbol(firDeclaration)
}
inline fun <reified D> D.unrollFakeOverrides(): D where D : FirDeclaration, D : FirSymbolOwner<*> {
internal inline fun <reified D> D.unrollFakeOverrides(): D where D : FirDeclaration, D : FirSymbolOwner<*> {
val symbol = symbol
if (symbol !is PossiblyFirFakeOverrideSymbol<*, *>) return this
if (!symbol.isFakeOverride) return this
if (!symbol.isFakeOrIntersectionOverride) return this
var current: FirBasedSymbol<*>? = symbol.overriddenSymbol
while (current is PossiblyFirFakeOverrideSymbol<*, *> && current.isFakeOverride) {
while (current is PossiblyFirFakeOverrideSymbol<*, *> && current.isFakeOrIntersectionOverride) {
current = current.overriddenSymbol
}
return current?.fir as D
}
private inline val FirBasedSymbol<*>.isFakeOrIntersectionOverride: Boolean
get() {
val origin = (fir as? FirDeclaration)?.origin ?: return false
return origin == FirDeclarationOrigin.FakeOverride || origin == FirDeclarationOrigin.IntersectionOverride
}
@@ -42,10 +42,8 @@ import org.jetbrains.kotlin.psi.*
internal class KtFirAnalysisSession
private constructor(
private val element: KtElement,
val firSession: FirSession,
val firResolveState: FirModuleResolveState,
internal val firSymbolBuilder: KtSymbolByFirBuilder,
private val typeContext: ConeTypeCheckerContext,
token: ValidityToken,
val isContextSession: Boolean,
) : KtAnalysisSession(token) {
@@ -54,7 +52,7 @@ private constructor(
override val symbolProvider: KtSymbolProvider =
KtFirSymbolProvider(
token,
firSession.firSymbolProvider,
firResolveState.firIdeLibrariesSession.firSymbolProvider,
firResolveState,
firSymbolBuilder
)
@@ -62,7 +60,7 @@ private constructor(
private val firScopeStorage = FirScopeRegistry()
override val scopeProvider: KtScopeProvider by threadLocal {
KtFirScopeProvider(token, firSymbolBuilder, project, firSession, firResolveState, firScopeStorage)
KtFirScopeProvider(token, firSymbolBuilder, project, firResolveState, firScopeStorage)
}
init {
@@ -111,7 +109,7 @@ private constructor(
assertIsValid()
var result = false
forEachSuperClass(klass.getOrBuildFirSafe(firResolveState) ?: return false) { type ->
result = result || type.firClassLike(firSession)?.symbol?.classId == superClassId
result = result || type.firClassLike(firResolveState.firIdeSourcesSession)?.symbol?.classId == superClassId
}
return result
}
@@ -130,10 +128,8 @@ private constructor(
val contextResolveState = LowLevelFirApiFacade.getResolveStateForCompletion(element, firResolveState)
return KtFirAnalysisSession(
element,
firSession,
contextResolveState,
firSymbolBuilder.createReadOnlyCopy(contextResolveState),
typeContext,
token,
isContextSession = true
)
@@ -149,7 +145,7 @@ private constructor(
}
private fun resolveCall(firCall: FirFunctionCall, callExpression: KtExpression): CallInfo? {
val session = firResolveState.firSession
val session = firResolveState.firIdeSourcesSession
val resolvedFunctionSymbol = firCall.calleeReference.toTargetSymbol(session, firSymbolBuilder)
val resolvedCalleeSymbol = (firCall.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol
return when {
@@ -204,23 +200,17 @@ private constructor(
@Deprecated("Please use org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProviderKt.analyze")
internal fun createForElement(element: KtElement): KtFirAnalysisSession {
val firResolveState = LowLevelFirApiFacade.getResolveStateFor(element)
val firSession = firResolveState.firSession
val project = element.project
val typeContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true, firSession)
val token = ReadActionConfinementValidityToken(project)
val firSymbolBuilder = KtSymbolByFirBuilder(
firSession.firSymbolProvider,
typeContext,
firResolveState,
project,
token
)
return KtFirAnalysisSession(
element,
firSession,
firResolveState,
firSymbolBuilder,
typeContext,
token,
isContextSession = false
)
@@ -9,10 +9,8 @@ import com.google.common.collect.MapMaker
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
@@ -157,8 +155,8 @@ internal class KtSymbolByFirBuilder private constructor(
(firProvider.getSymbolByLookupTag(lookupTag) as? FirTypeParameterSymbol)?.fir?.let(::buildTypeParameterSymbol)
}
fun buildClassLikeSymbolByClassId(classId: ClassId, firSession: FirSession): FirRegularClass? = withValidityAssertion {
firSession.firProvider.getClassLikeSymbolByFqName(classId)?.fir as? FirRegularClass
fun buildClassLikeSymbolByClassId(classId: ClassId): FirRegularClass? = withValidityAssertion {
firProvider.getClassLikeSymbolByFqName(classId)?.fir as? FirRegularClass
}
@@ -44,11 +44,9 @@ internal class KtFirScopeProvider(
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder,
private val project: Project,
session: FirSession,
firResolveState: FirModuleResolveState,
firScopeRegistry: FirScopeRegistry,
) : KtScopeProvider(), ValidityTokenOwner {
private val session by weakRef(session)
private val firResolveState by weakRef(firResolveState)
private val firScopeStorage by weakRef(firScopeRegistry)
@@ -78,8 +76,11 @@ internal class KtFirScopeProvider(
override fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope = withValidityAssertion {
packageMemberScopeCache.getOrPut(packageSymbol) {
val firPackageScope = FirPackageMemberScope(packageSymbol.fqName, session/*TODO use correct session here*/)
.also(firScopeStorage::register)
val firPackageScope =
FirPackageMemberScope(
packageSymbol.fqName,
firResolveState.firIdeSourcesSession/*TODO use correct session here*/
).also(firScopeStorage::register)
KtFirPackageScope(firPackageScope, builder, token)
}
}
@@ -89,9 +90,9 @@ internal class KtFirScopeProvider(
}
override fun getScopeForType(type: KtType): KtScope? {
check(type is KtFirType) { "KtFirScopePriovider can only work with KtFirType, but ${type::class} was provided" }
check(type is KtFirType) { "KtFirScopeProvider can only work with KtFirType, but ${type::class} was provided" }
val firTypeScope = type.coneType.scope(session, ScopeSession()) ?: return null
val firTypeScope = type.coneType.scope(firResolveState.firIdeSourcesSession, ScopeSession()) ?: return null
return convertToKtScope(firTypeScope)
}
@@ -7,19 +7,17 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
internal class KtFirAnonymousFunctionSymbol(
fir: FirAnonymousFunction,
@@ -38,5 +36,8 @@ internal class KtFirAnonymousFunctionSymbol(
}
}
override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol> = NonRestorableKtSymbolPointer
override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
error("Could not create a pointer for anonymous function from library")
}
}
@@ -12,9 +12,12 @@ import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.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.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirClassOrObjectInLibrarySymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -59,7 +62,10 @@ internal class KtFirClassOrObjectSymbol(
}
override fun createPointer(): KtSymbolPointer<KtClassOrObjectSymbol> {
val classId = classId
return symbolPointer { session -> session.symbolProvider.getClassOrObjectSymbolByClassId(classId) }
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
if (symbolKind == KtSymbolKind.LOCAL) {
throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(classId.asString())
}
return KtFirClassOrObjectInLibrarySymbol(classId)
}
}
@@ -9,19 +9,20 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.getPrimaryConstructorIfAny
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirConstructorSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.ClassId
@@ -60,17 +61,10 @@ internal class KtFirConstructorSymbol(
}
override fun createPointer(): KtSymbolPointer<KtConstructorSymbol> = withValidityAssertion {
if (!isPrimary) {
// TODO for now we can not find symbol for member function :(
return NonRestorableKtSymbolPointer
}
val ownerClassId = owner.classId
return symbolPointer { session ->
val ownerSymbol = session.symbolProvider.getClassOrObjectSymbolByClassId(ownerClassId) ?: return@symbolPointer null
check(ownerSymbol is KtFirSymbol<*>)
val classFir = ownerSymbol.firRef.withFir { (it as? FirRegularClass) }
?: error("FirRegularClass expected")
classFir.getPrimaryConstructorIfAny()?.let(builder::buildConstructorSymbol)
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
if (symbolKind == KtSymbolKind.LOCAL) {
throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException("${ownerClassId.asString()}.constructor")
}
return KtFirConstructorSymbolPointer(ownerClassId, isPrimary, firRef.withFir { it.createSignature() })
}
}
@@ -10,15 +10,12 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.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.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorParameterSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.Name
internal class KtFirConstructorValueParameterSymbol(
@@ -48,5 +45,10 @@ internal class KtFirConstructorValueParameterSymbol(
}
}
override val hasDefaultValue: Boolean get() = withValidityAssertion { fir.defaultValue != null }
override val hasDefaultValue: Boolean get() = firRef.withFir { it.defaultValue != null }
override fun createPointer(): KtSymbolPointer<KtConstructorParameterSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating symbols for library constructor parameters is not supported yet")
}
}
@@ -11,14 +11,15 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirEnumEntrySymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
internal class KtFirEnumEntrySymbol(
@@ -32,4 +33,10 @@ internal class KtFirEnumEntrySymbol(
override val name: Name get() = firRef.withFir { it.name }
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) }
override val enumClassId: ClassId = firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should present for enum") }
override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
return KtFirEnumEntrySymbolPointer(enumClassId, firRef.withFir { it.createSignature() })
}
}
@@ -11,17 +11,15 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirMemberFunctionSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -29,8 +27,7 @@ internal class KtFirFunctionSymbol(
fir: FirSimpleFunction,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder,
private val forcedOrigin: FirDeclarationOrigin? = null
private val builder: KtSymbolByFirBuilder
) : KtFunctionSymbol(), KtFirSymbol<FirSimpleFunction> {
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
@@ -48,7 +45,6 @@ internal class KtFirFunctionSymbol(
}
}
override val origin: KtSymbolOrigin get() = withValidityAssertion { forcedOrigin?.asKtSymbolOrigin() ?: super.origin }
override val isSuspend: Boolean get() = firRef.withFir { it.isSuspend }
override val receiverType: KtType? by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> fir.receiverTypeRef?.let(builder::buildKtType) }
override val isOperator: Boolean get() = firRef.withFir { it.isOperator }
@@ -63,4 +59,16 @@ internal class KtFirFunctionSymbol(
}
}
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override fun createPointer(): KtSymbolPointer<KtFunctionSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
return when (symbolKind) {
KtSymbolKind.TOP_LEVEL -> TODO("Creating symbol for top level fun is not supported yet")
KtSymbolKind.MEMBER -> KtFirMemberFunctionSymbolPointer(
firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should not be null for member function") },
firRef.withFir { it.createSignature() }
)
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(fqName?.asString() ?: name.asString())
}
}
}
@@ -11,14 +11,13 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.Name
internal class KtFirFunctionValueParameterSymbol(
@@ -34,5 +33,11 @@ internal class KtFirFunctionValueParameterSymbol(
override val isVararg: Boolean get() = firRef.withFir { it.isVararg }
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir -> builder.buildKtType(fir.returnTypeRef) }
override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
override val hasDefaultValue: Boolean get() = withValidityAssertion { fir.defaultValue != null }
override val hasDefaultValue: Boolean get() = firRef.withFir { it.defaultValue != null }
override fun createPointer(): KtSymbolPointer<KtFunctionParameterSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating pointers for functions parameters from library is not supported yet")
}
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtJavaFieldSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.name.Name
@@ -37,4 +38,8 @@ internal class KtFirJavaFieldSymbol(
override val name: Name get() = firRef.withFir { it.name }
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol> {
TODO("Creating pointers for java fields is not supported yet")
}
}
@@ -11,15 +11,15 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtLocalVariableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.Name
internal class KtFirLocalVariableSymbol(
@@ -40,4 +40,9 @@ internal class KtFirLocalVariableSymbol(
override val name: Name get() = firRef.withFir { it.name }
override val type: KtType by firRef.withFirAndCache(FirResolvePhase.BODY_RESOLVE) { fir -> builder.buildKtType(fir.returnTypeRef) }
override val symbolKind: KtSymbolKind get() = KtSymbolKind.LOCAL
override fun createPointer(): KtSymbolPointer<KtLocalVariableSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(name.asString())
}
}
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.symbolPointer
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
import org.jetbrains.kotlin.name.FqName
@@ -6,24 +6,23 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirMemberPropertySymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -31,8 +30,7 @@ internal class KtFirPropertySymbol(
fir: FirProperty,
resolveState: FirModuleResolveState,
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder,
private val forcedOrigin: FirDeclarationOrigin?
private val builder: KtSymbolByFirBuilder
) : KtPropertySymbol(), KtFirSymbol<FirProperty> {
init {
assert(!fir.isLocal)
@@ -41,7 +39,6 @@ internal class KtFirPropertySymbol(
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val origin: KtSymbolOrigin get() = withValidityAssertion { forcedOrigin?.asKtSymbolOrigin() ?: super.origin }
override val fqName: FqName get() = firRef.withFir { it.symbol.callableId.asFqNameForDebugInfo() }
override val isVal: Boolean get() = firRef.withFir { it.isVal }
@@ -57,4 +54,16 @@ internal class KtFirPropertySymbol(
}
}
override val modality: KtCommonSymbolModality get() = firRef.withFir { it.modality.getSymbolModality() }
override fun createPointer(): KtSymbolPointer<KtPropertySymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
return when (symbolKind) {
KtSymbolKind.TOP_LEVEL -> TODO("Creating symbol for top level fun is not supported yet")
KtSymbolKind.MEMBER -> KtFirMemberPropertySymbolPointer(
firRef.withFir { it.symbol.callableId.classId ?: error("ClassId should not be null for member property") },
firRef.withFir { it.createSignature() }
)
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(fqName.asString())
}
}
}
@@ -10,13 +10,10 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.ReadOnlyWeakRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeAliasSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -29,4 +26,9 @@ internal class KtFirTypeAliasSymbol(
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val name: Name get() = firRef.withFir { it.name }
override val classId: ClassId get() = firRef.withFir { it.symbol.classId }
override fun createPointer(): KtSymbolPointer<KtTypeAliasSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating symbols for library typealiases is not supported yet")
}
}
@@ -10,12 +10,10 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.Name
internal class KtFirTypeParameterSymbol(
@@ -27,4 +25,9 @@ internal class KtFirTypeParameterSymbol(
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val name: Name get() = firRef.withFir { it.name }
override fun createPointer(): KtSymbolPointer<KtTypeParameterSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating symbols for library type parameters is not supported yet")
}
}
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCommonSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolModality
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.psi.KtDeclaration
internal inline fun <reified M : KtSymbolModality> Modality?.getSymbolModality(): M = when (this) {
Modality.FINAL -> KtCommonSymbolModality.FINAL
@@ -0,0 +1,22 @@
/*
* 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.pointers
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
class KtFirClassOrObjectInLibrarySymbol(private val classId: ClassId) : KtSymbolPointer<KtClassOrObjectSymbol>() {
override fun restoreSymbol(analysisSession: KtAnalysisSession): KtClassOrObjectSymbol? {
require(analysisSession is KtFirAnalysisSession)
val firClass = analysisSession.firSymbolBuilder.buildClassLikeSymbolByClassId(
classId
) ?: return null
return analysisSession.firSymbolBuilder.buildClassSymbol(firClass)
}
}
@@ -0,0 +1,30 @@
/*
* 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.pointers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.ClassId
internal class KtFirConstructorSymbolPointer(
ownerClassId: ClassId,
private val isPrimary: Boolean,
private val signature: IdSignature
) : KtFirMemberSymbolPointer<KtConstructorSymbol>(ownerClassId) {
override fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: Collection<FirDeclaration>,
firSession: FirSession
): KtConstructorSymbol? {
val firConstructor = candidates.findDeclarationWithSignature<FirConstructor>(signature, firSession) ?: return null
if (firConstructor.isPrimary != isPrimary) return null
return firSymbolBuilder.buildConstructorSymbol(firConstructor)
}
}
@@ -0,0 +1,28 @@
/*
* 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.pointers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.ClassId
internal class KtFirEnumEntrySymbolPointer(
ownerClassId: ClassId,
private val signature: IdSignature
) : KtFirMemberSymbolPointer<KtEnumEntrySymbol>(ownerClassId) {
override fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: Collection<FirDeclaration>,
firSession: FirSession
): KtEnumEntrySymbol? {
val firProperty = candidates.findDeclarationWithSignature<FirEnumEntry>(signature, firSession) ?: return null
return firSymbolBuilder.buildEnumEntrySymbol(firProperty)
}
}
@@ -0,0 +1,28 @@
/*
* 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.pointers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.ClassId
internal class KtFirMemberFunctionSymbolPointer(
ownerClassId: ClassId,
private val signature: IdSignature
) : KtFirMemberSymbolPointer<KtFunctionSymbol>(ownerClassId) {
override fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: Collection<FirDeclaration>,
firSession: FirSession
): KtFunctionSymbol? {
val firFunction = candidates.findDeclarationWithSignature<FirSimpleFunction>(signature, firSession) ?: return null
return firSymbolBuilder.buildFunctionSymbol(firFunction)
}
}
@@ -0,0 +1,28 @@
/*
* 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.pointers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.ClassId
internal class KtFirMemberPropertySymbolPointer(
ownerClassId: ClassId,
private val signature: IdSignature
) : KtFirMemberSymbolPointer<KtPropertySymbol>(ownerClassId) {
override fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: Collection<FirDeclaration>,
firSession: FirSession
): KtPropertySymbol? {
val firProperty = candidates.findDeclarationWithSignature<FirProperty>(signature, firSession) ?: return null
return firSymbolBuilder.buildVariableSymbol(firProperty) as? KtPropertySymbol
}
}
@@ -0,0 +1,32 @@
/*
* 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.pointers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.name.ClassId
internal abstract class KtFirMemberSymbolPointer<S : KtSymbol>(
private val ownerClassId: ClassId,
) : KtSymbolPointer<S>() {
final override fun restoreSymbol(analysisSession: KtAnalysisSession): S? {
require(analysisSession is KtFirAnalysisSession)
val owner = analysisSession.firSymbolBuilder.buildClassLikeSymbolByClassId(
ownerClassId
) ?: return null
return analysisSession.chooseCandidateAndCreateSymbol(owner.declarations, owner.session)
}
protected abstract fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: Collection<FirDeclaration>,
firSession: FirSession
): S?
}
@@ -0,0 +1,37 @@
/*
* 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.pointers
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.Fir2IrSignatureComposer
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmMangleComputer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
import org.jetbrains.kotlin.fir.signaturer.FirMangler
import org.jetbrains.kotlin.idea.fir.low.level.api.ideSessionComponents
import org.jetbrains.kotlin.ir.util.IdSignature
internal inline fun <reified D : FirDeclaration> Collection<FirDeclaration>.findDeclarationWithSignature(
signature: IdSignature,
firSession: FirSession
): D? {
val signatureComposer = firSession.ideSessionComponents.signatureComposer
for (declaration in this) {
if (declaration is D && signatureComposer.composeSignature(declaration) == signature) {
return declaration
}
}
return null
}
internal fun FirDeclaration.createSignature(): IdSignature {
val signatureComposer = session.ideSessionComponents.signatureComposer
return signatureComposer.composeSignature(this)
?: error("Could not compose signature for declaration, looks like it is private or local")
}
@@ -133,7 +133,7 @@ internal object FirReferenceResolveHelper {
val expression = ref.expression
val symbolBuilder = analysisSession.firSymbolBuilder
val fir = expression.getOrBuildFir(analysisSession.firResolveState)
val session = analysisSession.firSession
val session = analysisSession.firResolveState.firIdeSourcesSession
when (fir) {
is FirResolvable -> {
val calleeReference =
@@ -0,0 +1,13 @@
// RUNTIME
class: kotlin/Lazy
// SYMBOLS:
KtFirClassOrObjectSymbol:
classId: kotlin/Lazy
classKind: INTERFACE
modality: ABSTRACT
name: Lazy
origin: LIBRARY
symbolKind: TOP_LEVEL
typeParameters: [KtFirTypeParameterSymbol(T)]
@@ -0,0 +1,13 @@
// RUNTIME
class: java.lang.String
// SYMBOLS:
KtFirClassOrObjectSymbol:
classId: java.lang.String
classKind: CLASS
modality: FINAL
name: String
origin: JAVA
symbolKind: MEMBER
typeParameters: []
@@ -0,0 +1,11 @@
// RUNTIME
callable: kotlin/LazyThreadSafetyMode.SYNCHRONIZED
// SYMBOLS:
KtFirEnumEntrySymbol:
enumClassId: kotlin/LazyThreadSafetyMode
name: SYNCHRONIZED
origin: LIBRARY
symbolKind: MEMBER
type: kotlin/LazyThreadSafetyMode
@@ -0,0 +1,16 @@
callable: kotlin/collections/List.get
// SYMBOLS:
KtFirFunctionSymbol:
fqName: kotlin.collections.List.get
isExtension: false
isOperator: true
isSuspend: false
modality: ABSTRACT
name: get
origin: LIBRARY
receiverType: null
symbolKind: MEMBER
type: E
typeParameters: []
valueParameters: [KtFirFunctionValueParameterSymbol(index)]
@@ -0,0 +1,30 @@
callable: kotlin/collections/List.listIterator
// SYMBOLS:
KtFirFunctionSymbol:
fqName: kotlin.collections.List.listIterator
isExtension: false
isOperator: false
isSuspend: false
modality: ABSTRACT
name: listIterator
origin: LIBRARY
receiverType: null
symbolKind: MEMBER
type: kotlin/collections/ListIterator<E>
typeParameters: []
valueParameters: []
KtFirFunctionSymbol:
fqName: kotlin.collections.List.listIterator
isExtension: false
isOperator: false
isSuspend: false
modality: ABSTRACT
name: listIterator
origin: LIBRARY
receiverType: null
symbolKind: MEMBER
type: kotlin/collections/ListIterator<E>
typeParameters: []
valueParameters: [KtFirFunctionValueParameterSymbol(index)]
@@ -0,0 +1,11 @@
class: kotlin/collections/MutableMap.MutableEntry
// SYMBOLS:
KtFirClassOrObjectSymbol:
classId: kotlin/collections/MutableMap.MutableEntry
classKind: INTERFACE
modality: ABSTRACT
name: MutableEntry
origin: LIBRARY
symbolKind: MEMBER
typeParameters: [KtFirTypeParameterSymbol(K), KtFirTypeParameterSymbol(V)]
+11 -1
View File
@@ -1,2 +1,12 @@
class A {
}
}
// SYMBOLS:
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
typeParameters: []
@@ -1,2 +1,21 @@
class A() {
}
}
// SYMBOLS:
KtFirConstructorSymbol:
isPrimary: true
origin: SOURCE
owner: KtFirClassOrObjectSymbol(A)
ownerClassId: A
symbolKind: MEMBER
type: A
valueParameters: []
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
typeParameters: []
@@ -0,0 +1,62 @@
class A() {
constructor(x: Int): this()
constructor(y: Int, z: String) : this(y)
}
// SYMBOLS:
KtFirConstructorSymbol:
isPrimary: true
origin: SOURCE
owner: KtFirClassOrObjectSymbol(A)
ownerClassId: A
symbolKind: MEMBER
type: A
valueParameters: []
KtFirFunctionValueParameterSymbol:
isVararg: false
name: x
origin: SOURCE
symbolKind: LOCAL
type: kotlin/Int
KtFirConstructorSymbol:
isPrimary: false
origin: SOURCE
owner: KtFirClassOrObjectSymbol(A)
ownerClassId: A
symbolKind: MEMBER
type: A
valueParameters: Could not render due to java.lang.ClassCastException: org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirFunctionValueParameterSymbol cannot be cast to org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirConstructorValueParameterSymbol
KtFirFunctionValueParameterSymbol:
isVararg: false
name: y
origin: SOURCE
symbolKind: LOCAL
type: kotlin/Int
KtFirFunctionValueParameterSymbol:
isVararg: false
name: z
origin: SOURCE
symbolKind: LOCAL
type: kotlin/String
KtFirConstructorSymbol:
isPrimary: false
origin: SOURCE
owner: KtFirClassOrObjectSymbol(A)
ownerClassId: A
symbolKind: MEMBER
type: A
valueParameters: Could not render due to java.lang.ClassCastException: org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirFunctionValueParameterSymbol cannot be cast to org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirConstructorValueParameterSymbol
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
typeParameters: []
+27
View File
@@ -0,0 +1,27 @@
enum class X {
Y, Z;
}
// SYMBOLS:
KtFirEnumEntrySymbol:
enumClassId: X
name: Y
origin: SOURCE
symbolKind: MEMBER
type: X
KtFirEnumEntrySymbol:
enumClassId: X
name: Z
origin: SOURCE
symbolKind: MEMBER
type: X
KtFirClassOrObjectSymbol:
classId: X
classKind: ENUM_CLASS
modality: FINAL
name: X
origin: SOURCE
symbolKind: TOP_LEVEL
typeParameters: []
@@ -0,0 +1,42 @@
class A {
fun x(): Int
fun y()
}
// SYMBOLS:
KtFirFunctionSymbol:
fqName: A.x
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: x
origin: SOURCE
receiverType: null
symbolKind: MEMBER
type: kotlin/Int
typeParameters: []
valueParameters: []
KtFirFunctionSymbol:
fqName: A.y
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: y
origin: SOURCE
receiverType: null
symbolKind: MEMBER
type: kotlin/Unit
typeParameters: []
valueParameters: []
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
typeParameters: []
@@ -0,0 +1,36 @@
class A {
val x: Int = 10
val Int.y = this
}
// SYMBOLS:
KtFirPropertySymbol:
fqName: A.x
isExtension: false
isVal: true
modality: FINAL
name: x
origin: SOURCE
receiverType: kotlin/Int
symbolKind: MEMBER
type: kotlin/Int
KtFirPropertySymbol:
fqName: A.y
isExtension: true
isVal: true
modality: FINAL
name: y
origin: SOURCE
receiverType: A
symbolKind: MEMBER
type: A
KtFirClassOrObjectSymbol:
classId: A
classKind: CLASS
modality: FINAL
name: A
origin: SOURCE
symbolKind: TOP_LEVEL
typeParameters: []
@@ -0,0 +1,31 @@
fun x(): Int = 10
fun y() {}
// SYMBOLS:
KtFirFunctionSymbol:
fqName: x
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: x
origin: SOURCE
receiverType: null
symbolKind: TOP_LEVEL
type: kotlin/Int
typeParameters: []
valueParameters: []
KtFirFunctionSymbol:
fqName: y
isExtension: false
isOperator: false
isSuspend: false
modality: FINAL
name: y
origin: SOURCE
receiverType: null
symbolKind: TOP_LEVEL
type: kotlin/Unit
typeParameters: []
valueParameters: []
@@ -0,0 +1,25 @@
val x: Int = 10
val Int.y = this
// SYMBOLS:
KtFirPropertySymbol:
fqName: x
isExtension: false
isVal: true
modality: FINAL
name: x
origin: SOURCE
receiverType: kotlin/Int
symbolKind: TOP_LEVEL
type: kotlin/Int
KtFirPropertySymbol:
fqName: y
isExtension: true
isVal: true
modality: FINAL
name: y
origin: SOURCE
receiverType: ERROR CLASS: Unresolved this@null
symbolKind: TOP_LEVEL
type: ERROR CLASS: Unresolved this@null
@@ -5,18 +5,12 @@
package org.jetbrains.kotlin.idea.frontend.api
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.low.level.api.LowLevelFirApiFacade
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.DebugSymbolRenderer
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
@@ -25,12 +19,7 @@ abstract class AbstractSymbolByFqNameTest : KotlinLightCodeInsightFixtureTestCas
protected fun doTest(path: String) {
val fakeKtFile = myFixture.configureByText("file.kt", "fun a() {}") as KtFile
val testDataFile = File(path)
val testFileText = FileUtil.loadFile(testDataFile)
val identifier = testFileText.substringBeforeLast(SYMBOLS_TAG).trim()
val symbolData = SymbolData.create(identifier)
val symbolData = SymbolByFqName.getSymbolDataFromFile(path)
val renderedSymbols = executeOnPooledThreadInReadAction {
analyze(fakeKtFile) {
@@ -39,59 +28,13 @@ abstract class AbstractSymbolByFqNameTest : KotlinLightCodeInsightFixtureTestCas
}
}
val actual = buildString {
val actualSymbolsData = renderedSymbols.joinToString(separator = "\n")
val fileTextWithoutSymbolsData = testFileText.substringBeforeLast(SYMBOLS_TAG).trimEnd()
appendLine(fileTextWithoutSymbolsData)
appendLine()
appendLine(SYMBOLS_TAG)
append(actualSymbolsData)
}
KotlinTestUtils.assertEqualsToFile(testDataFile, actual)
val actual = SymbolByFqName.textWithRenderedSymbolData(path, renderedSymbols.joinToString(separator = "\n"))
KotlinTestUtils.assertEqualsToFile(File(path), actual)
}
protected abstract fun createSymbols(symbolData: SymbolData, analysisSession: KtAnalysisSession): List<KtSymbol>
override fun getDefaultProjectDescriptor(): KotlinLightProjectDescriptor =
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
companion object {
private const val SYMBOLS_TAG = "// SYMBOLS:"
}
}
sealed class SymbolData {
abstract fun toSymbols(analysisSession: KtAnalysisSession): List<KtSymbol>
data class ClassData(val classId: ClassId) : SymbolData() {
override fun toSymbols(analysisSession: KtAnalysisSession): List<KtSymbol> {
val symbol = analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(classId) ?: error("Class $classId is not found")
return listOf(symbol)
}
}
data class CallableData(val packageName: FqName, val name: Name) : SymbolData() {
override fun toSymbols(analysisSession: KtAnalysisSession): List<KtSymbol> {
val symbols = analysisSession.symbolProvider.getTopLevelCallableSymbols(packageName, name).toList()
if (symbols.isEmpty()) {
error("No callable with fqName ${packageName}/${name} found")
}
return symbols
}
}
companion object {
fun create(data: String): SymbolData = when {
data.startsWith("class:") -> ClassData(ClassId.fromString(data.removePrefix("class:").trim()))
data.startsWith("callable:") -> {
val fullName = data.removePrefix("callable:").trim()
val name = Name.identifier(fullName.substringAfterLast("/"))
val fqName = FqName(fullName.substringBeforeLast("/").replace('/', '.'))
CallableData(fqName, name)
}
else -> error("Invalid symbol")
}
}
}
@@ -0,0 +1,90 @@
/*
* 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
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtNamedSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import java.io.File
object SymbolByFqName {
fun getSymbolDataFromFile(filePath: String): SymbolData {
val testFileText = FileUtil.loadFile(File(filePath))
val identifier = testFileText.lineSequence().first { line -> SymbolData.identifiers.any { line.startsWith(it) } }
return SymbolData.create(identifier)
}
fun textWithRenderedSymbolData(filePath: String, rendered: String): String = buildString {
val testFileText = FileUtil.loadFile(File(filePath))
val fileTextWithoutSymbolsData = testFileText.substringBeforeLast(SYMBOLS_TAG).trimEnd()
appendLine(fileTextWithoutSymbolsData)
appendLine()
appendLine(SYMBOLS_TAG)
append(rendered)
}
private const val SYMBOLS_TAG = "// SYMBOLS:"
}
sealed class SymbolData {
abstract fun toSymbols(analysisSession: KtAnalysisSession): List<KtSymbol>
data class ClassData(val classId: ClassId) : SymbolData() {
override fun toSymbols(analysisSession: KtAnalysisSession): List<KtSymbol> {
val symbol = analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(classId) ?: error("Class $classId is not found")
return listOf(symbol)
}
}
data class CallableData(val callableId: CallableId) : SymbolData() {
override fun toSymbols(analysisSession: KtAnalysisSession): List<KtSymbol> {
val classId = callableId.classId
val symbols = if (classId == null) {
analysisSession.symbolProvider.getTopLevelCallableSymbols(callableId.packageName, callableId.callableName).toList()
} else {
val classSymbol =
analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(classId)
?: error("Class $classId is not found")
analysisSession.scopeProvider.getDeclaredMemberScope(classSymbol).getCallableSymbols()
.filter { (it as? KtNamedSymbol)?.name == callableId.callableName }
.toList()
}
if (symbols.isEmpty()) {
error("No callable with fqName $callableId found")
}
return symbols
}
}
companion object {
val identifiers = arrayOf("callable:", "class:")
fun create(data: String): SymbolData = when {
data.startsWith("class:") -> ClassData(ClassId.fromString(data.removePrefix("class:").trim()))
data.startsWith("callable:") -> {
val fullName = data.removePrefix("callable:").trim()
val name = if ('.' in fullName) fullName.substringAfterLast(".") else fullName.substringAfterLast('/')
val (packageName, className) = run {
val packageNameWithClassName = fullName.dropLast(name.length + 1)
when {
'.' in fullName ->
packageNameWithClassName.substringBeforeLast('/') to packageNameWithClassName.substringAfterLast('/')
else -> packageNameWithClassName to null
}
}
CallableData(CallableId(FqName(packageName.replace('/', '.')), className?.let { FqName(it) }, Name.identifier(name)))
}
else -> error("Invalid symbol")
}
}
}
@@ -0,0 +1,18 @@
/*
* 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 com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.SymbolByFqName
import org.jetbrains.kotlin.psi.KtFile
abstract class AbstractSymbolFromLibraryPointerRestoreTest : AbstractSymbolPointerRestoreTest() {
override fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List<KtSymbol> {
val symbolData = SymbolByFqName.getSymbolDataFromFile(filePath)
return symbolData.toSymbols(this)
}
}
@@ -0,0 +1,18 @@
/*
* 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.KtAnalysisSession
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
abstract class AbstractSymbolFromSourcePointerRestoreTest : AbstractSymbolPointerRestoreTest() {
override fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List<KtSymbol> =
ktFile.collectDescendantsOfType<KtDeclaration>().map { declaration ->
symbolProvider.getSymbol(declaration)
}
}
@@ -0,0 +1,81 @@
/*
* 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 com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.SymbolByFqName
import org.jetbrains.kotlin.idea.frontend.api.analyze
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.util.suffixIfNot
import org.junit.Assert
import java.io.File
abstract class AbstractSymbolPointerRestoreTest : KotlinLightCodeInsightFixtureTestCase() {
abstract fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List<KtSymbol>
protected fun doTest(path: String) {
val file = File(path)
val ktFile = myFixture.configureByText(file.name.suffixIfNot(".kt"), FileUtil.loadFile(file)) as KtFile
val pointersWithRendered = executeOnPooledThreadInReadAction {
analyze(ktFile) {
collectSymbols(path, ktFile).map { symbol ->
PointerWithRenderedSymbol(
symbol.createPointer(),
DebugSymbolRenderer.render(symbol)
)
}
}
}
val actual = SymbolByFqName.textWithRenderedSymbolData(
path,
pointersWithRendered.joinToString(separator = "\n") { it.rendered },
)
KotlinTestUtils.assertEqualsToFile(File(path), actual)
CommandProcessor.getInstance().runUndoTransparentAction {
runWriteAction {
KtPsiFactory(ktFile).apply {
ktFile.add(createNewLine(lineBreaks = 2))
ktFile.add(createProperty("val aaaaaa: Int = 10"))
}
PsiDocumentManager.getInstance(project).apply {
commitDocument(getDocument(ktFile) ?: error("Cannot find document for ktFile"))
}
}
}
// another read action
executeOnPooledThreadInReadAction {
analyze(ktFile) {
val restored = pointersWithRendered.map { (pointer, expectedRender) ->
val restored = pointer.restoreSymbol(this) ?: error("Symbol $expectedRender was not not restored correctly")
DebugSymbolRenderer.render(restored)
}
val actualRestored = SymbolByFqName.textWithRenderedSymbolData(
path,
restored.joinToString(separator = "\n"),
)
KotlinTestUtils.assertEqualsToFile(File(path), actualRestored)
}
}
}
}
private data class PointerWithRenderedSymbol(val pointer: KtSymbolPointer<*>, val rendered: String)
@@ -1,56 +0,0 @@
/*
* 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 com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.addExternalTestFiles
import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.analyze
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.getAnalysisSessionFor
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.junit.Assert
import java.io.File
abstract class AbstractSymbolPointerTest : KotlinLightCodeInsightFixtureTestCase() {
protected fun doTest(path: String) {
val file = File(path)
val ktFile = myFixture.configureByText(file.name, FileUtil.loadFile(file)) as KtFile
val pointers = executeOnPooledThreadInReadAction {
analyze(ktFile) {
val declarationSymbols = ktFile.collectDescendantsOfType<KtDeclaration>().map { declaration ->
symbolProvider.getSymbol(declaration)
}
declarationSymbols.map { PointerWithPsi(it.createPointer(), it.psi!!) }
}
}
// another read action
executeOnPooledThreadInReadAction {
analyze(ktFile) {
pointers.forEach { (pointer, psi) ->
val restored = pointer.restoreSymbol(this) ?: error("Symbol $psi was not not restored correctly")
Assert.assertEquals(restored.psi!!, psi)
}
}
}
}
}
private data class PointerWithPsi(val pointer: KtSymbolPointer<*>, val psi: PsiElement)
@@ -0,0 +1,60 @@
/*
* 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 com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class SymbolFromLibraryPointerRestoreTestGenerated extends AbstractSymbolFromLibraryPointerRestoreTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInResoreSymbolFromLibrary() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary"), Pattern.compile("^(.+)\\.txt$"), null, true);
}
@TestMetadata("class.txt")
public void testClass() throws Exception {
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/class.txt");
}
@TestMetadata("classFromJdk.txt")
public void testClassFromJdk() throws Exception {
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/classFromJdk.txt");
}
@TestMetadata("enumEntry.txt")
public void testEnumEntry() throws Exception {
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/enumEntry.txt");
}
@TestMetadata("memberFunction.txt")
public void testMemberFunction() throws Exception {
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/memberFunction.txt");
}
@TestMetadata("memberFunctionWithOverloads.txt")
public void testMemberFunctionWithOverloads() throws Exception {
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/memberFunctionWithOverloads.txt");
}
@TestMetadata("nestedClass.txt")
public void testNestedClass() throws Exception {
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/nestedClass.txt");
}
}
@@ -19,7 +19,7 @@ import java.util.regex.Pattern;
@TestMetadata("idea/idea-frontend-fir/testData/symbolPointer")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class SymbolPointerTestGenerated extends AbstractSymbolPointerTest {
public class SymbolFromSourcePointerRestoreTestGenerated extends AbstractSymbolFromSourcePointerRestoreTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@@ -37,4 +37,34 @@ public class SymbolPointerTestGenerated extends AbstractSymbolPointerTest {
public void testClassPrimaryConstructor() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbolPointer/classPrimaryConstructor.kt");
}
@TestMetadata("classSecondaryConstructors.kt")
public void testClassSecondaryConstructors() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbolPointer/classSecondaryConstructors.kt");
}
@TestMetadata("enum.kt")
public void testEnum() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbolPointer/enum.kt");
}
@TestMetadata("memberFunctions.kt")
public void testMemberFunctions() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbolPointer/memberFunctions.kt");
}
@TestMetadata("memberProperties.kt")
public void testMemberProperties() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbolPointer/memberProperties.kt");
}
@TestMetadata("topLevelFunctions.kt")
public void testTopLevelFunctions() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbolPointer/topLevelFunctions.kt");
}
@TestMetadata("topLevelProperties.kt")
public void testTopLevelProperties() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbolPointer/topLevelProperties.kt");
}
}