diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt index f8d419c1cb7..fdb9efcf0b5 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirClassInitializerSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.types.Variance @@ -68,6 +69,7 @@ internal class KtSymbolByFirBuilder private constructor( val functionLikeBuilder = FunctionLikeSymbolBuilder() val variableLikeBuilder = VariableLikeSymbolBuilder() val callableBuilder = CallableSymbolBuilder() + val anonymousInitializerBuilder = AnonymousInitializerBuilder() val typeBuilder = TypeBuilder() constructor( @@ -337,6 +339,12 @@ internal class KtSymbolByFirBuilder private constructor( } } + inner class AnonymousInitializerBuilder { + fun buildClassInitializer(fir: FirAnonymousInitializer): KtClassInitializerSymbol { + return symbolsCache.cache(fir) { KtFirClassInitializerSymbol(fir, resolveState, token) } + } + } + inner class TypeBuilder { fun buildKtType(coneType: ConeKotlinType): KtType { return typesCache.cache(coneType) { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirClassInitializerSymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirClassInitializerSymbol.kt new file mode 100644 index 00000000000..b797a6f0919 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirClassInitializerSymbol.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2021 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.analysis.api.fir.symbols + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.api.fir.findPsi +import org.jetbrains.kotlin.analysis.api.fir.utils.firRef +import org.jetbrains.kotlin.analysis.api.symbols.KtClassInitializerSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState +import org.jetbrains.kotlin.fir.declarations.FirAnonymousInitializer + +internal class KtFirClassInitializerSymbol( + fir: FirAnonymousInitializer, + resolveState: FirModuleResolveState, + override val token: ValidityToken, +) : KtClassInitializerSymbol(), KtFirSymbol { + override val firRef = firRef(fir, resolveState) + override val psi: PsiElement? by firRef.withFirAndCache { fir -> fir.findPsi(fir.moduleData.session) } + + override fun createPointer(): KtSymbolPointer { + TODO("Figure out how to create such a pointer. Should we give an index to class initializers?") + } + + override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt index 606976fdd29..176f08c19fb 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSymbolProvider.kt @@ -5,11 +5,6 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.renderWithType -import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.* import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder @@ -17,6 +12,15 @@ import org.jetbrains.kotlin.analysis.api.fir.utils.weakRef import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken import org.jetbrains.kotlin.analysis.api.withValidityAssertion +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirOfType +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.withFirDeclarationOfType +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.renderWithType +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtClassInitializerSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -130,6 +134,12 @@ internal class KtFirSymbolProvider( } } + override fun getClassInitializerSymbol(psi: KtClassInitializer): KtClassInitializerSymbol = withValidityAssertion { + psi.withFirDeclarationOfType(resolveState) { + firSymbolBuilder.anonymousInitializerBuilder.buildClassInitializer(it) + } + } + override fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol? = withValidityAssertion { val symbol = firSymbolProvider.getClassLikeSymbolByClassId(classId) as? FirRegularClassSymbol ?: return null firSymbolBuilder.classifierBuilder.buildNamedClassOrObjectSymbol(symbol.fir) diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/symbols/SymbolByPsiTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/symbols/SymbolByPsiTestGenerated.java index 4371f881688..c4158e2f6ef 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/symbols/SymbolByPsiTestGenerated.java +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/symbols/SymbolByPsiTestGenerated.java @@ -48,6 +48,12 @@ public class SymbolByPsiTestGenerated extends AbstractSymbolByPsiTest { runTest("analysis/analysis-api/testData/symbols/symbolByPsi/class.kt"); } + @Test + @TestMetadata("classInitializer.kt") + public void testClassInitializer() throws Exception { + runTest("analysis/analysis-api/testData/symbols/symbolByPsi/classInitializer.kt"); + } + @Test @TestMetadata("classMembes.kt") public void testClassMembes() throws Exception { diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtClassInitializerSymbol.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtClassInitializerSymbol.kt new file mode 100644 index 00000000000..98d622655fb --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtClassInitializerSymbol.kt @@ -0,0 +1,10 @@ +/* + * Copyright 2010-2021 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.analysis.api.symbols + +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind + +public abstract class KtClassInitializerSymbol : KtSymbol, KtSymbolWithKind \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt index 977d7fb29e4..b35aadccb40 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/KtSymbolProvider.kt @@ -27,6 +27,7 @@ public abstract class KtSymbolProvider : KtAnalysisSessionComponent() { literalExpression?.let(::getAnonymousObjectSymbol) ?: getClassOrObjectSymbol(psi) } is KtPropertyAccessor -> getPropertyAccessorSymbol(psi) + is KtClassInitializer -> getClassInitializerSymbol(psi) else -> error("Cannot build symbol for ${psi::class}") } @@ -44,6 +45,7 @@ public abstract class KtSymbolProvider : KtAnalysisSessionComponent() { public abstract fun getClassOrObjectSymbol(psi: KtClassOrObject): KtClassOrObjectSymbol public abstract fun getNamedClassOrObjectSymbol(psi: KtClassOrObject): KtNamedClassOrObjectSymbol? public abstract fun getPropertyAccessorSymbol(psi: KtPropertyAccessor): KtPropertyAccessorSymbol + public abstract fun getClassInitializerSymbol(psi: KtClassInitializer): KtClassInitializerSymbol public abstract fun getClassOrObjectSymbolByClassId(classId: ClassId): KtClassOrObjectSymbol? diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/classInitializer.kt b/analysis/analysis-api/testData/symbols/symbolByPsi/classInitializer.kt new file mode 100644 index 00000000000..8df6cd9bbd6 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/classInitializer.kt @@ -0,0 +1,8 @@ +// DO_NOT_CHECK_SYMBOL_RESTORE + +class A { + val i: Int + init { + i = 1 + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/symbols/symbolByPsi/classInitializer.txt b/analysis/analysis-api/testData/symbols/symbolByPsi/classInitializer.txt new file mode 100644 index 00000000000..18ed4c96302 --- /dev/null +++ b/analysis/analysis-api/testData/symbols/symbolByPsi/classInitializer.txt @@ -0,0 +1,57 @@ +KtFirKotlinPropertySymbol: + annotatedType: [] kotlin/Int + annotationClassIds: [] + annotations: [] + callableIdIfNonLocal: /A.i + dispatchType: A + getter: KtFirPropertyGetterSymbol() + hasBackingField: true + hasGetter: true + hasSetter: false + initializer: null + isConst: false + isExtension: false + isFromPrimaryConstructor: false + isLateInit: false + isOverride: false + isStatic: false + isVal: true + modality: FINAL + name: i + origin: SOURCE + receiverType: null + setter: null + symbolKind: MEMBER + visibility: Public + deprecationStatus: null + getterDeprecationStatus: null + javaGetterName: getI + javaSetterName: null + setterDeprecationStatus: null + +KtFirClassInitializerSymbol: + origin: SOURCE + symbolKind: MEMBER + deprecationStatus: null + +KtFirNamedClassOrObjectSymbol: + annotationClassIds: [] + annotations: [] + classIdIfNonLocal: A + classKind: CLASS + companionObject: null + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: A + origin: SOURCE + superTypes: [ + [] kotlin/Any + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + deprecationStatus: null