AA: introduce new APIs to get containing file (symbol) and JvmClassName
^KTIJ-27686
This commit is contained in:
committed by
Space Team
parent
5b6363b0df
commit
797174ee1f
+106
-8
@@ -11,23 +11,28 @@ import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtSymbolContainingDeclarationProvider
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.KtFe10DescDefaultBackingFieldSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.KtFe10DynamicFunctionDescValueParameterSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.getDescriptor
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.getModule
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtBackingFieldSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
|
||||
import org.jetbrains.kotlin.load.kotlin.*
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.platform
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import java.nio.file.Path
|
||||
@@ -46,13 +51,89 @@ internal class KtFe10SymbolContainingDeclarationProvider(
|
||||
|
||||
return when (symbol) {
|
||||
is KtBackingFieldSymbol -> symbol.owningProperty
|
||||
else -> symbol.getDescriptor()?.containingDeclaration?.toKtSymbol(analysisContext) as? KtDeclarationSymbol
|
||||
is KtPropertyAccessorSymbol -> {
|
||||
(symbol.getDescriptor() as? PropertyAccessorDescriptor)?.correspondingProperty
|
||||
?.toKtSymbol(analysisContext) as? KtDeclarationSymbol
|
||||
}
|
||||
else -> {
|
||||
symbol.getDescriptor()?.containingDeclaration
|
||||
?.toKtSymbol(analysisContext) as? KtDeclarationSymbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val KtSymbol.containingSymbolOrSelf: KtSymbol
|
||||
get() {
|
||||
return when (this) {
|
||||
is KtValueParameterSymbol -> {
|
||||
getContainingDeclaration(this) as? KtFunctionLikeSymbol ?: this
|
||||
}
|
||||
is KtPropertyAccessorSymbol -> {
|
||||
getContainingDeclaration(this) as? KtPropertySymbol ?: this
|
||||
}
|
||||
is KtBackingFieldSymbol -> this.owningProperty
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContainingFileSymbol(symbol: KtSymbol): KtFileSymbol? {
|
||||
if (symbol is KtFileSymbol) return null
|
||||
// psiBased
|
||||
(symbol.psi?.containingFile as? KtFile)?.let { ktFile ->
|
||||
with(analysisSession) {
|
||||
return ktFile.getFileSymbol()
|
||||
}
|
||||
}
|
||||
// descriptorBased
|
||||
val descriptor = symbol.containingSymbolOrSelf.getDescriptor()
|
||||
val ktFile = descriptor?.let(DescriptorToSourceUtils::getContainingFile) ?: return null
|
||||
with(analysisSession) {
|
||||
return ktFile.getFileSymbol()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContainingJvmClassName(symbol: KtCallableSymbol): JvmClassName? {
|
||||
val platform = getContainingModule(symbol).platform
|
||||
if (!platform.isCommon() && !platform.isJvm()) return null
|
||||
|
||||
val containingSymbolOrSelf = symbol.containingSymbolOrSelf as KtSymbolWithKind
|
||||
return when (val descriptor = containingSymbolOrSelf.getDescriptor()) {
|
||||
is DescriptorWithContainerSource -> {
|
||||
when (val containerSource = descriptor.containerSource) {
|
||||
is FacadeClassSource -> containerSource.facadeClassName ?: containerSource.className
|
||||
is KotlinJvmBinarySourceElement -> JvmClassName.byClassId(containerSource.binaryClass.classId)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
return if (containingSymbolOrSelf.symbolKind == KtSymbolKind.TOP_LEVEL) {
|
||||
descriptor?.let(DescriptorToSourceUtils::getContainingFile)
|
||||
?.takeUnless { it.isScript() }
|
||||
?.let { JvmClassName.byFqNameWithoutInnerClasses(it.javaFileFacadeFqName) }
|
||||
} else {
|
||||
val classId = (containingSymbolOrSelf as? KtConstructorSymbol)?.containingClassIdIfNonLocal
|
||||
?: (containingSymbolOrSelf as? KtCallableSymbol)?.callableIdIfNonLocal?.classId
|
||||
classId?.takeUnless { it.shortClassName.isSpecial }
|
||||
?.let { JvmClassName.byClassId(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO this is a dummy and incorrect implementation just to satisfy some tests
|
||||
override fun getContainingModule(symbol: KtSymbol): KtModule {
|
||||
val descriptor = symbol.getDescriptor()
|
||||
val descriptor = when (symbol) {
|
||||
is KtValueParameterSymbol -> {
|
||||
val paramDescriptor = symbol.getDescriptor()
|
||||
(paramDescriptor as? ValueParameterDescriptor)?.containingDeclaration ?: paramDescriptor
|
||||
}
|
||||
is KtPropertyAccessorSymbol -> {
|
||||
val accessorDescriptor = symbol.getDescriptor()
|
||||
(accessorDescriptor as? PropertyAccessorDescriptor)?.correspondingProperty ?: accessorDescriptor
|
||||
}
|
||||
else ->
|
||||
symbol.getDescriptor()
|
||||
}
|
||||
|
||||
val symbolPsi = descriptor?.let(DescriptorToSourceUtils::getContainingFile) ?: symbol.psi
|
||||
if (symbolPsi != null) {
|
||||
@@ -75,7 +156,24 @@ internal class KtFe10SymbolContainingDeclarationProvider(
|
||||
}
|
||||
|
||||
private fun getFakeContainingKtModule(descriptor: DescriptorWithContainerSource): KtModule {
|
||||
val libraryPath = Paths.get((descriptor.containerSource as JvmPackagePartSource).knownJvmBinaryClass?.containingLibrary!!)
|
||||
val library = when (val containerSource = descriptor.containerSource) {
|
||||
is JvmPackagePartSource -> containerSource.knownJvmBinaryClass?.containingLibrary
|
||||
is KotlinJvmBinarySourceElement -> containerSource.binaryClass.containingLibrary
|
||||
else -> {
|
||||
when (val containingDeclaration = descriptor.containingDeclaration) {
|
||||
is DescriptorWithContainerSource -> {
|
||||
// Deserialized member
|
||||
return getFakeContainingKtModule(containingDeclaration)
|
||||
}
|
||||
is LazyJavaPackageFragment -> {
|
||||
// Deserialized top-level
|
||||
(containingDeclaration.source as KotlinJvmBinarySourceElement).binaryClass.containingLibrary
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
} ?: TODO(descriptor::class.java.name)
|
||||
val libraryPath = Paths.get(library)
|
||||
return object : KtLibraryModule {
|
||||
override val libraryName: String = libraryPath.fileName.toString().substringBeforeLast(".")
|
||||
override val librarySources: KtLibrarySourceModule? = null
|
||||
|
||||
+1
-1
@@ -139,8 +139,8 @@ internal fun KtSymbol.getDescriptor(): DeclarationDescriptor? {
|
||||
is KtFe10DescSymbol<*> -> descriptor
|
||||
is KtFe10DescSyntheticFieldSymbol -> descriptor
|
||||
is KtFe10PsiDefaultPropertyGetterSymbol -> descriptor
|
||||
is KtFe10PsiDefaultPropertySetterSymbol -> descriptor
|
||||
is KtFe10PsiDefaultSetterParameterSymbol -> descriptor
|
||||
is KtFe10PsiDefaultPropertySetterSymbol -> null
|
||||
is KtFe10DescDefaultPropertySetterSymbol -> null
|
||||
is KtFe10DynamicFunctionDescValueParameterSymbol -> null
|
||||
is KtFe10FileSymbol -> null
|
||||
|
||||
+12
@@ -172,6 +172,12 @@ public class Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends A
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/extensionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("facadeWithJvmName.kt")
|
||||
public void testFacadeWithJvmName() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/facadeWithJvmName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forLoopVariable.kt")
|
||||
public void testForLoopVariable() throws Exception {
|
||||
@@ -250,6 +256,12 @@ public class Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends A
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/memberProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multifilePart.kt")
|
||||
public void testMultifilePart() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/multifilePart.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("outerAndInnerClasses.kt")
|
||||
public void testOuterAndInnerClasses() throws Exception {
|
||||
|
||||
+54
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtSymbolContainingDeclarationProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirReceiverParameterSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.firSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.getContainingKtModule
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.withSymbolAttachment
|
||||
@@ -17,20 +18,26 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.jvmClassNameIfDeserialized
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirScript
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirErrorPropertySymbol
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.psi
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
internal class KtFirSymbolContainingDeclarationProvider(
|
||||
@@ -53,7 +60,7 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
||||
if (firSymbol is FirErrorPropertySymbol && firSymbol.diagnostic is ConeDestructuringDeclarationsOnTopLevel) return null
|
||||
fun getParentSymbolByPsi() = getContainingPsi(symbol).let { with(analysisSession) { it.getSymbol() } }
|
||||
return when (symbol) {
|
||||
is KtPropertyAccessorSymbol -> firSymbolBuilder.buildSymbol(symbol.firSymbol.fir.propertySymbol) as? KtDeclarationSymbol
|
||||
is KtPropertyAccessorSymbol -> firSymbolBuilder.buildSymbol(symbol.firSymbol.propertySymbol) as? KtDeclarationSymbol
|
||||
is KtBackingFieldSymbol -> symbol.owningProperty
|
||||
is KtTypeParameterSymbol -> firSymbolBuilder.buildSymbol(symbol.firSymbol.containingDeclarationSymbol) as? KtDeclarationSymbol
|
||||
is KtLocalVariableSymbol -> getParentSymbolByPsi()
|
||||
@@ -98,11 +105,56 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContainingFileSymbol(symbol: KtSymbol): KtFileSymbol? {
|
||||
if (symbol is KtFileSymbol) return null
|
||||
val firSymbol = when (symbol) {
|
||||
is KtFirReceiverParameterSymbol -> {
|
||||
// symbol from receiver parameter
|
||||
symbol.firSymbol
|
||||
}
|
||||
else -> {
|
||||
// general FIR-based symbol
|
||||
symbol.firSymbol
|
||||
}
|
||||
}
|
||||
val firFileSymbol = firSymbol.fir.getContainingFile()?.symbol ?: return null
|
||||
return firSymbolBuilder.buildFileSymbol(firFileSymbol)
|
||||
}
|
||||
|
||||
override fun getContainingJvmClassName(symbol: KtCallableSymbol): JvmClassName? {
|
||||
val platform = getContainingModule(symbol).platform
|
||||
if (!platform.isCommon() && !platform.isJvm()) return null
|
||||
|
||||
val containingSymbolOrSelf = when (symbol) {
|
||||
is KtValueParameterSymbol -> {
|
||||
getContainingDeclaration(symbol) as? KtFunctionLikeSymbol ?: symbol
|
||||
}
|
||||
is KtPropertyAccessorSymbol -> {
|
||||
getContainingDeclaration(symbol) as? KtPropertySymbol ?: symbol
|
||||
}
|
||||
is KtBackingFieldSymbol -> symbol.owningProperty
|
||||
else -> symbol
|
||||
}
|
||||
val firSymbol = containingSymbolOrSelf.firSymbol
|
||||
|
||||
firSymbol.jvmClassNameIfDeserialized()?.let { return it }
|
||||
|
||||
return if (containingSymbolOrSelf.symbolKind == KtSymbolKind.TOP_LEVEL) {
|
||||
(firSymbol.fir.getContainingFile()?.psi as? KtFile)
|
||||
?.takeUnless { it.isScript() }
|
||||
?.let { JvmClassName.byFqNameWithoutInnerClasses(it.javaFileFacadeFqName) }
|
||||
} else {
|
||||
val classId = (containingSymbolOrSelf as? KtConstructorSymbol)?.containingClassIdIfNonLocal
|
||||
?: containingSymbolOrSelf.callableIdIfNonLocal?.classId
|
||||
classId?.takeUnless { it.shortClassName.isSpecial }
|
||||
?.let { JvmClassName.byClassId(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContainingModule(symbol: KtSymbol): KtModule {
|
||||
return symbol.getContainingKtModule(analysisSession.firResolveSession)
|
||||
}
|
||||
|
||||
|
||||
private fun getContainingPsi(symbol: KtSymbol): KtDeclaration {
|
||||
val source = symbol.firSymbol.source
|
||||
val thisSource = when (source?.kind) {
|
||||
|
||||
+12
@@ -172,6 +172,12 @@ public class FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends Ab
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/extensionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("facadeWithJvmName.kt")
|
||||
public void testFacadeWithJvmName() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/facadeWithJvmName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forLoopVariable.kt")
|
||||
public void testForLoopVariable() throws Exception {
|
||||
@@ -250,6 +256,12 @@ public class FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends Ab
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/memberProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multifilePart.kt")
|
||||
public void testMultifilePart() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/multifilePart.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("outerAndInnerClasses.kt")
|
||||
public void testOuterAndInnerClasses() throws Exception {
|
||||
|
||||
+17
-4
@@ -6,12 +6,12 @@
|
||||
package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.checkContainingFileSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.checkContainingJvmClassName
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtScriptSymbol
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtScriptInitializer
|
||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
@@ -19,7 +19,9 @@ import org.jetbrains.kotlin.test.services.assertions
|
||||
abstract class AbstractContainingDeclarationProviderByPsiTest : AbstractAnalysisApiSingleFileTest() {
|
||||
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
|
||||
val currentPath = mutableListOf<KtDeclaration>()
|
||||
val ktClasses = mutableListOf<KtClassOrObject>()
|
||||
analyseForTest(ktFile.declarations.first()) {
|
||||
val expectedFileSymbol = ktFile.getFileSymbol()
|
||||
ktFile.accept(object : KtVisitorVoid() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
element.acceptChildren(this)
|
||||
@@ -39,9 +41,20 @@ abstract class AbstractContainingDeclarationProviderByPsiTest : AbstractAnalysis
|
||||
}
|
||||
}
|
||||
|
||||
checkContainingFileSymbol(expectedFileSymbol, currentDeclarationSymbol, testServices)
|
||||
if (currentDeclarationSymbol is KtCallableSymbol) {
|
||||
checkContainingJvmClassName(ktFile, ktClasses.lastOrNull(), currentDeclarationSymbol, testServices)
|
||||
}
|
||||
|
||||
currentPath.add(dcl)
|
||||
if (dcl is KtClassOrObject) {
|
||||
ktClasses.add(dcl)
|
||||
}
|
||||
super.visitDeclaration(dcl)
|
||||
currentPath.removeLast()
|
||||
if (dcl is KtClassOrObject) {
|
||||
ktClasses.removeLast()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+4
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiRecursiveElementVisitor
|
||||
import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForDebug
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.DebugSymbolRenderer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
|
||||
@@ -35,9 +36,12 @@ abstract class AbstractMultiModuleSymbolByPsiTest : AbstractAnalysisApiBasedTest
|
||||
prettyPrinter.appendLine(fileDirective)
|
||||
|
||||
analyseForTest(file) {
|
||||
val fileSymbol = file.getFileSymbol()
|
||||
file.forEachDescendantOfType<KtDeclaration>(predicate = { it.isValidForSymbolCreation }) { declaration ->
|
||||
val symbol = declaration.getSymbol()
|
||||
|
||||
checkContainingFileSymbol(fileSymbol, symbol, testServices)
|
||||
|
||||
debugPrinter.appendLine(debugRenderer.render(symbol))
|
||||
debugPrinter.appendLine()
|
||||
|
||||
|
||||
+3
@@ -91,6 +91,9 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
|
||||
val pointersWithRendered = executeOnPooledThreadInReadAction {
|
||||
analyseForTest(ktFile) {
|
||||
val (symbols, symbolForPrettyRendering) = collectSymbols(ktFile, testServices)
|
||||
for (symbol in symbols) {
|
||||
checkContainingFileSymbol(ktFile.getFileSymbol(), symbol, testServices)
|
||||
}
|
||||
|
||||
val pointerWithRenderedSymbol = symbols
|
||||
.asSequence()
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.impl.base.test.cases.symbols
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
|
||||
context(KtAnalysisSession)
|
||||
internal fun checkContainingFileSymbol(
|
||||
ktFileSymbol: KtFileSymbol,
|
||||
symbol: KtSymbol,
|
||||
testServices: TestServices
|
||||
) {
|
||||
if (symbol.origin != KtSymbolOrigin.SOURCE) return
|
||||
val containingFileSymbol = symbol.getContainingFileSymbol()
|
||||
testServices.assertions.assertEquals(ktFileSymbol, containingFileSymbol) {
|
||||
"Invalid file for $symbol, expected $ktFileSymbol but $containingFileSymbol found"
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
internal fun checkContainingJvmClassName(
|
||||
ktFile: KtFile,
|
||||
ktClass: KtClassOrObject?,
|
||||
symbol: KtCallableSymbol,
|
||||
testServices: TestServices
|
||||
) {
|
||||
if (ktFile.isScript()) return
|
||||
val expectedClassName = when {
|
||||
symbol.symbolKind == KtSymbolKind.LOCAL ->
|
||||
null
|
||||
ktClass != null ->
|
||||
// member
|
||||
ktClass.getClassId()?.let { JvmClassName.byClassId(it) }
|
||||
else ->
|
||||
// top-level
|
||||
JvmClassName.byFqNameWithoutInnerClasses(ktFile.javaFileFacadeFqName)
|
||||
}
|
||||
val actualClassName = symbol.getContainingJvmClassName()
|
||||
testServices.assertions.assertEquals(expectedClassName, actualClassName) {
|
||||
"Invalid JvmClassName for $symbol, expected $expectedClassName but $actualClassName found"
|
||||
}
|
||||
}
|
||||
+12
@@ -172,6 +172,12 @@ public class FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated ext
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/extensionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("facadeWithJvmName.kt")
|
||||
public void testFacadeWithJvmName() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/facadeWithJvmName.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forLoopVariable.kt")
|
||||
public void testForLoopVariable() throws Exception {
|
||||
@@ -250,6 +256,12 @@ public class FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated ext
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/memberProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multifilePart.kt")
|
||||
public void testMultifilePart() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/multifilePart.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("outerAndInnerClasses.kt")
|
||||
public void testOuterAndInnerClasses() throws Exception {
|
||||
|
||||
+26
-1
@@ -6,14 +6,20 @@
|
||||
package org.jetbrains.kotlin.analysis.api.components
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
|
||||
public abstract class KtSymbolContainingDeclarationProvider : KtAnalysisSessionComponent() {
|
||||
public abstract fun getContainingDeclaration(symbol: KtSymbol): KtDeclarationSymbol?
|
||||
|
||||
public abstract fun getContainingFileSymbol(symbol: KtSymbol): KtFileSymbol?
|
||||
|
||||
public abstract fun getContainingJvmClassName(symbol: KtCallableSymbol): JvmClassName?
|
||||
|
||||
public abstract fun getContainingModule(symbol: KtSymbol): KtModule
|
||||
}
|
||||
|
||||
@@ -27,6 +33,25 @@ public interface KtSymbolContainingDeclarationProviderMixIn : KtAnalysisSessionM
|
||||
public fun KtSymbol.getContainingSymbol(): KtDeclarationSymbol? =
|
||||
withValidityAssertion { analysisSession.containingDeclarationProvider.getContainingDeclaration(this) }
|
||||
|
||||
/**
|
||||
* Returns containing [KtFile] as [KtFileSymbol]
|
||||
*
|
||||
* Caveat: returns null if the given symbol is already [KtFileSymbol], since there is no containing file.
|
||||
*/
|
||||
public fun KtSymbol.getContainingFileSymbol(): KtFileSymbol? =
|
||||
withValidityAssertion { analysisSession.containingDeclarationProvider.getContainingFileSymbol(this) }
|
||||
|
||||
/**
|
||||
* Returns containing class's [JvmClassName] if any for [KtCallableSymbol]
|
||||
*
|
||||
* even for deserialized callables! (which is useful to look up the containing facade in [PsiElement])
|
||||
* for regular, non-local callables from source, it is a mere conversion of [ClassId] inside [CallableId]
|
||||
*
|
||||
* Note that this API is applicable for common or JVM modules only.
|
||||
*/
|
||||
public fun KtCallableSymbol.getContainingJvmClassName(): JvmClassName? =
|
||||
withValidityAssertion { analysisSession.containingDeclarationProvider.getContainingJvmClassName(this) }
|
||||
|
||||
public fun KtSymbol.getContainingModule(): KtModule =
|
||||
withValidityAssertion { analysisSession.containingDeclarationProvider.getContainingModule(this) }
|
||||
}
|
||||
+19
-2
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -71,9 +72,24 @@ public class DebugSymbolRenderer(
|
||||
KtSymbolContainingDeclarationProviderMixIn::class
|
||||
.declaredMemberExtensionFunctions
|
||||
.filter { it.name == "getContainingModule" }
|
||||
.filterNot {
|
||||
// Rendering a containing symbol is prone to stack overflow.
|
||||
// * function symbol will render its value parameter symbol(s)
|
||||
// whose containing symbol is that function symbol.
|
||||
// * property symbol contains accessor symbol(s) and/or backing field symbol
|
||||
// whose containing symbol is that property symbol.
|
||||
it.name == "getContainingSymbol"
|
||||
}
|
||||
.forEach {
|
||||
appendLine()
|
||||
renderFunction(it, renderSymbolsFully = false, this@KtAnalysisSession, symbol)
|
||||
if (it.name == "getContainingJvmClassName") {
|
||||
if (symbol is KtCallableSymbol) {
|
||||
appendLine()
|
||||
renderFunction(it, renderSymbolsFully = false, this@KtAnalysisSession, symbol)
|
||||
}
|
||||
} else {
|
||||
appendLine()
|
||||
renderFunction(it, renderSymbolsFully = false, this@KtAnalysisSession, symbol)
|
||||
}
|
||||
}
|
||||
|
||||
KtSymbolInfoProviderMixIn::class.declaredMemberExtensionProperties
|
||||
@@ -188,6 +204,7 @@ public class DebugSymbolRenderer(
|
||||
is KtClassLikeSymbol -> renderId(symbol.classIdIfNonLocal, symbol)
|
||||
is KtCallableSymbol -> renderId(symbol.callableIdIfNonLocal, symbol)
|
||||
is KtNamedSymbol -> renderValue(symbol.name, renderSymbolsFully = false)
|
||||
is KtFileSymbol -> renderValue((symbol.psi as KtFile).name, renderSymbolsFully = false)
|
||||
else -> error("Unsupported symbol ${symbol::class}")
|
||||
}
|
||||
append(")")
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
|
||||
@file:kotlin.jvm.JvmName("DifferentFacadeName")
|
||||
|
||||
fun foo() {}
|
||||
|
||||
fun String.foo(): Int = 42
|
||||
|
||||
val x: Int = 42
|
||||
|
||||
val Int.y get() = this
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fun foo()
|
||||
|
||||
fun kotlin.String.foo(): kotlin.Int
|
||||
|
||||
val x: kotlin.Int
|
||||
|
||||
val kotlin.Int.y: kotlin.Int
|
||||
get()
|
||||
@@ -0,0 +1,244 @@
|
||||
KtFunctionSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: /foo
|
||||
contextReceivers: []
|
||||
contractEffects: []
|
||||
hasStableParameterNames: true
|
||||
isActual: false
|
||||
isBuiltinFunctionInvoke: false
|
||||
isExpect: false
|
||||
isExtension: false
|
||||
isExternal: false
|
||||
isInfix: false
|
||||
isInline: false
|
||||
isOperator: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isSuspend: false
|
||||
modality: FINAL
|
||||
name: foo
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Unit
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
|
||||
KtFunctionSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: /foo
|
||||
contextReceivers: []
|
||||
contractEffects: []
|
||||
hasStableParameterNames: true
|
||||
isActual: false
|
||||
isBuiltinFunctionInvoke: false
|
||||
isExpect: false
|
||||
isExtension: true
|
||||
isExternal: false
|
||||
isInfix: false
|
||||
isInline: false
|
||||
isOperator: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isSuspend: false
|
||||
modality: FINAL
|
||||
name: foo
|
||||
origin: SOURCE
|
||||
receiverParameter: KtReceiverParameterSymbol:
|
||||
annotationsList: []
|
||||
origin: SOURCE
|
||||
owningCallableSymbol: KtFunctionSymbol(/foo)
|
||||
type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/String
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
|
||||
KtKotlinPropertySymbol:
|
||||
annotationsList: []
|
||||
backingFieldSymbol: KtBackingFieldSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
name: field
|
||||
origin: PROPERTY_BACKING_FIELD
|
||||
owningProperty: KtKotlinPropertySymbol(/x)
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
callableIdIfNonLocal: /x
|
||||
contextReceivers: []
|
||||
getter: KtPropertyGetterSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
hasBody: false
|
||||
hasStableParameterNames: true
|
||||
isDefault: true
|
||||
isExtension: false
|
||||
isInline: false
|
||||
isOverride: false
|
||||
modality: FINAL
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: ACCESSOR
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
hasBackingField: true
|
||||
hasGetter: true
|
||||
hasSetter: false
|
||||
initializer: KtConstantInitializerValue(42)
|
||||
isActual: false
|
||||
isConst: false
|
||||
isDelegatedProperty: false
|
||||
isExpect: false
|
||||
isExtension: false
|
||||
isFromPrimaryConstructor: false
|
||||
isLateInit: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isVal: true
|
||||
modality: FINAL
|
||||
name: x
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
setter: null
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
getterDeprecationStatus: null
|
||||
javaGetterName: getX
|
||||
javaSetterName: null
|
||||
setterDeprecationStatus: null
|
||||
|
||||
KtKotlinPropertySymbol:
|
||||
annotationsList: []
|
||||
backingFieldSymbol: KtBackingFieldSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
name: field
|
||||
origin: PROPERTY_BACKING_FIELD
|
||||
owningProperty: KtKotlinPropertySymbol(/y)
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
callableIdIfNonLocal: /y
|
||||
contextReceivers: []
|
||||
getter: KtPropertyGetterSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
hasBody: true
|
||||
hasStableParameterNames: true
|
||||
isDefault: false
|
||||
isExtension: false
|
||||
isInline: false
|
||||
isOverride: false
|
||||
modality: FINAL
|
||||
origin: SOURCE
|
||||
receiverParameter: KtReceiverParameterSymbol:
|
||||
annotationsList: []
|
||||
origin: SOURCE
|
||||
owningCallableSymbol: KtKotlinPropertySymbol(/y)
|
||||
type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: ACCESSOR
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
hasBackingField: false
|
||||
hasGetter: true
|
||||
hasSetter: false
|
||||
initializer: null
|
||||
isActual: false
|
||||
isConst: false
|
||||
isDelegatedProperty: false
|
||||
isExpect: false
|
||||
isExtension: true
|
||||
isFromPrimaryConstructor: false
|
||||
isLateInit: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isVal: true
|
||||
modality: FINAL
|
||||
name: y
|
||||
origin: SOURCE
|
||||
receiverParameter: KtReceiverParameterSymbol:
|
||||
annotationsList: []
|
||||
origin: SOURCE
|
||||
owningCallableSymbol: KtKotlinPropertySymbol(/y)
|
||||
type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
setter: null
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
getterDeprecationStatus: null
|
||||
javaGetterName: getY
|
||||
javaSetterName: null
|
||||
setterDeprecationStatus: null
|
||||
@@ -0,0 +1,11 @@
|
||||
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
|
||||
@file:kotlin.jvm.JvmMultifileClass
|
||||
@file:kotlin.jvm.JvmName("NotMultiFilePartKt")
|
||||
|
||||
fun foo() {}
|
||||
|
||||
fun String.foo(): Int = 42
|
||||
|
||||
val x: Int = 42
|
||||
|
||||
val Int.y get() = this
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo()
|
||||
|
||||
fun kotlin.String.foo(): kotlin.Int
|
||||
|
||||
val x: kotlin.Int
|
||||
|
||||
val kotlin.Int.y: kotlin.Int
|
||||
get()
|
||||
@@ -0,0 +1,244 @@
|
||||
KtFunctionSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: /foo
|
||||
contextReceivers: []
|
||||
contractEffects: []
|
||||
hasStableParameterNames: true
|
||||
isActual: false
|
||||
isBuiltinFunctionInvoke: false
|
||||
isExpect: false
|
||||
isExtension: false
|
||||
isExternal: false
|
||||
isInfix: false
|
||||
isInline: false
|
||||
isOperator: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isSuspend: false
|
||||
modality: FINAL
|
||||
name: foo
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Unit
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
|
||||
KtFunctionSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: /foo
|
||||
contextReceivers: []
|
||||
contractEffects: []
|
||||
hasStableParameterNames: true
|
||||
isActual: false
|
||||
isBuiltinFunctionInvoke: false
|
||||
isExpect: false
|
||||
isExtension: true
|
||||
isExternal: false
|
||||
isInfix: false
|
||||
isInline: false
|
||||
isOperator: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isSuspend: false
|
||||
modality: FINAL
|
||||
name: foo
|
||||
origin: SOURCE
|
||||
receiverParameter: KtReceiverParameterSymbol:
|
||||
annotationsList: []
|
||||
origin: SOURCE
|
||||
owningCallableSymbol: KtFunctionSymbol(/foo)
|
||||
type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/String
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
|
||||
KtKotlinPropertySymbol:
|
||||
annotationsList: []
|
||||
backingFieldSymbol: KtBackingFieldSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
name: field
|
||||
origin: PROPERTY_BACKING_FIELD
|
||||
owningProperty: KtKotlinPropertySymbol(/x)
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
callableIdIfNonLocal: /x
|
||||
contextReceivers: []
|
||||
getter: KtPropertyGetterSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
hasBody: false
|
||||
hasStableParameterNames: true
|
||||
isDefault: true
|
||||
isExtension: false
|
||||
isInline: false
|
||||
isOverride: false
|
||||
modality: FINAL
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: ACCESSOR
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
hasBackingField: true
|
||||
hasGetter: true
|
||||
hasSetter: false
|
||||
initializer: KtConstantInitializerValue(42)
|
||||
isActual: false
|
||||
isConst: false
|
||||
isDelegatedProperty: false
|
||||
isExpect: false
|
||||
isExtension: false
|
||||
isFromPrimaryConstructor: false
|
||||
isLateInit: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isVal: true
|
||||
modality: FINAL
|
||||
name: x
|
||||
origin: SOURCE
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
setter: null
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
getterDeprecationStatus: null
|
||||
javaGetterName: getX
|
||||
javaSetterName: null
|
||||
setterDeprecationStatus: null
|
||||
|
||||
KtKotlinPropertySymbol:
|
||||
annotationsList: []
|
||||
backingFieldSymbol: KtBackingFieldSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
isExtension: false
|
||||
name: field
|
||||
origin: PROPERTY_BACKING_FIELD
|
||||
owningProperty: KtKotlinPropertySymbol(/y)
|
||||
receiverParameter: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: LOCAL
|
||||
typeParameters: []
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
callableIdIfNonLocal: /y
|
||||
contextReceivers: []
|
||||
getter: KtPropertyGetterSymbol:
|
||||
annotationsList: []
|
||||
callableIdIfNonLocal: null
|
||||
contextReceivers: []
|
||||
hasBody: true
|
||||
hasStableParameterNames: true
|
||||
isDefault: false
|
||||
isExtension: false
|
||||
isInline: false
|
||||
isOverride: false
|
||||
modality: FINAL
|
||||
origin: SOURCE
|
||||
receiverParameter: KtReceiverParameterSymbol:
|
||||
annotationsList: []
|
||||
origin: SOURCE
|
||||
owningCallableSymbol: KtKotlinPropertySymbol(/y)
|
||||
type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
symbolKind: ACCESSOR
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
hasBackingField: false
|
||||
hasGetter: true
|
||||
hasSetter: false
|
||||
initializer: null
|
||||
isActual: false
|
||||
isConst: false
|
||||
isDelegatedProperty: false
|
||||
isExpect: false
|
||||
isExtension: true
|
||||
isFromPrimaryConstructor: false
|
||||
isLateInit: false
|
||||
isOverride: false
|
||||
isStatic: false
|
||||
isVal: true
|
||||
modality: FINAL
|
||||
name: y
|
||||
origin: SOURCE
|
||||
receiverParameter: KtReceiverParameterSymbol:
|
||||
annotationsList: []
|
||||
origin: SOURCE
|
||||
owningCallableSymbol: KtKotlinPropertySymbol(/y)
|
||||
type: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
returnType: KtUsualClassType:
|
||||
annotationsList: []
|
||||
ownTypeArguments: []
|
||||
type: kotlin/Int
|
||||
setter: null
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: Public
|
||||
getContainingModule: KtSourceModule "Sources of main"
|
||||
deprecationStatus: null
|
||||
getterDeprecationStatus: null
|
||||
javaGetterName: getY
|
||||
javaSetterName: null
|
||||
setterDeprecationStatus: null
|
||||
+1
-15
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.JvmStubDeserializedBuiltInsContainerSource
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.StubBasedFirDeserializedSymbolProvider
|
||||
import org.jetbrains.kotlin.analysis.utils.collections.buildSmartList
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
@@ -17,7 +16,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -169,7 +167,7 @@ internal class LLFirDependenciesSymbolProvider(
|
||||
if (newSymbols.isEmpty()) return
|
||||
val newFacades = SmartSet.create<JvmClassName>()
|
||||
for (symbol in newSymbols) {
|
||||
val facade = symbol.jvmClassName()
|
||||
val facade = symbol.jvmClassNameIfDeserialized()
|
||||
if (facade != null) {
|
||||
newFacades += facade
|
||||
if (facade !in facades) {
|
||||
@@ -181,16 +179,4 @@ internal class LLFirDependenciesSymbolProvider(
|
||||
}
|
||||
facades += newFacades
|
||||
}
|
||||
|
||||
private fun FirCallableSymbol<*>.jvmClassName(): JvmClassName? {
|
||||
val containerSource = fir.containerSource
|
||||
|
||||
return when (containerSource) {
|
||||
is JvmStubDeserializedBuiltInsContainerSource -> containerSource.facadeClassName
|
||||
|
||||
is FacadeClassSource -> containerSource.facadeClassName ?: containerSource.className
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
@@ -5,6 +5,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.DeserializedContainerSourceWithJvmClassName
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.JvmStubDeserializedBuiltInsContainerSource
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.util.*
|
||||
|
||||
internal fun <T: Any> Optional<T>.getOrNull(): T? = orElse(null)
|
||||
|
||||
fun FirCallableSymbol<*>.jvmClassNameIfDeserialized(): JvmClassName? {
|
||||
return when (val containerSource = fir.containerSource) {
|
||||
is JvmStubDeserializedBuiltInsContainerSource -> containerSource.facadeClassName
|
||||
is FacadeClassSource -> containerSource.facadeClassName ?: containerSource.className
|
||||
is DeserializedContainerSourceWithJvmClassName -> containerSource.className
|
||||
is KotlinJvmBinarySourceElement -> JvmClassName.byClassId(containerSource.binaryClass.classId)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.low.level.api.fir.stubBased.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
interface DeserializedContainerSourceWithJvmClassName : DeserializedContainerSource {
|
||||
val className: JvmClassName
|
||||
}
|
||||
+2
-2
@@ -14,8 +14,8 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
||||
|
||||
//required for LLFirDependenciesSymbolProvider#jvmClassName, to resolve ambiguities
|
||||
//todo check if moving builtins to stubs would solve the issue
|
||||
internal class JvmStubDeserializedContainerSource(classId: ClassId) : DeserializedContainerSource {
|
||||
private val className = JvmClassName.byClassId(classId)
|
||||
internal class JvmStubDeserializedContainerSource(classId: ClassId) : DeserializedContainerSourceWithJvmClassName {
|
||||
override val className = JvmClassName.byClassId(classId)
|
||||
|
||||
override val incompatibility: IncompatibleVersionErrorData<*>?
|
||||
get() = null
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
|
||||
internal class JvmStubDeserializedFacadeContainerSource(
|
||||
override val className: JvmClassName,
|
||||
override val facadeClassName: JvmClassName?
|
||||
) : DeserializedContainerSource, FacadeClassSource {
|
||||
) : DeserializedContainerSourceWithJvmClassName, FacadeClassSource {
|
||||
override val incompatibility: IncompatibleVersionErrorData<*>?
|
||||
get() = null
|
||||
|
||||
|
||||
+11
-1
@@ -25,7 +25,17 @@ fun FirElementWithResolveState.getContainingFile(): FirFile? {
|
||||
is FirBackingField -> propertySymbol.fir.getContainingFile()
|
||||
is FirCallableDeclaration -> provider.getFirCallableContainerFile(symbol)
|
||||
is FirClassLikeDeclaration -> provider.getFirClassifierContainerFileIfAny(symbol)
|
||||
is FirAnonymousInitializer -> containingDeclarationSymbol?.fir?.getContainingFile()
|
||||
is FirAnonymousInitializer -> {
|
||||
val classId = containingClassIdOrNull()
|
||||
if (classId?.isLocal == true) {
|
||||
containingKtFileIfAny?.let {
|
||||
val moduleComponents = llFirResolvableSession?.moduleComponents
|
||||
moduleComponents?.cache?.getCachedFirFile(it)
|
||||
}
|
||||
} else {
|
||||
containingDeclarationSymbol?.fir?.getContainingFile()
|
||||
}
|
||||
}
|
||||
is FirDanglingModifierList, is FirCodeFragment -> {
|
||||
val ktFile = psi?.containingFile as? KtFile
|
||||
?: error("File for dangling modifier list cannot be null")
|
||||
|
||||
Reference in New Issue
Block a user