[Analysis API] Fix 'getContainingDeclaration()' for foreign values

Foreign values (such as '_DebugLabel' properties contributed by the
debugger) don't have a parent (or a valid source element in general).

^KTIJ-27382 Fixed
This commit is contained in:
Yan Zhulanow
2024-02-01 00:48:24 +09:00
committed by Space Team
parent 88a85b8936
commit 2dd16e1179
3 changed files with 21 additions and 15 deletions
@@ -19,6 +19,7 @@ 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.compile.isForeignValue
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
@@ -36,6 +37,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLe
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.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.platform.has
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
import org.jetbrains.kotlin.psi
@@ -135,22 +137,23 @@ internal class KtFirSymbolContainingDeclarationProvider(
return false
}
is KtSymbolWithKind -> {
if (symbol.symbolKind == KtSymbolKind.TOP_LEVEL) {
val containingFile = (symbol.firSymbol.fir as? FirElementWithResolveState)?.getContainingFile()
if (containingFile == null || containingFile.declarations.firstOrNull() !is FirScript) {
// Should be replaced with proper check after KT-61451 and KT-61887
return false
}
}
else -> {}
}
return true
}
else -> {
return true
if (symbol is KtSymbolWithKind && symbol.symbolKind == KtSymbolKind.TOP_LEVEL) {
val containingFile = (symbol.firSymbol.fir as? FirElementWithResolveState)?.getContainingFile()
if (containingFile == null || containingFile.declarations.firstOrNull() !is FirScript) {
// Should be replaced with proper check after KT-61451 and KT-61887
return false
}
}
val firSymbol = symbol.firSymbol
if (firSymbol is FirPropertySymbol && firSymbol.isForeignValue) {
return false
}
return true
}
fun getContainingDeclarationByPsi(symbol: KtSymbol): KtDeclarationSymbol? {
@@ -189,7 +189,7 @@ private class CodeFragmentCapturedValueVisitor(
if (symbol.isLocal) {
val isCrossingInlineBounds = isCrossingInlineBounds(element, symbol)
val capturedValue = when {
symbol.fir.foreignValueMarker == true -> CodeFragmentCapturedValue.ForeignValue(symbol.name, isCrossingInlineBounds)
symbol.isForeignValue -> CodeFragmentCapturedValue.ForeignValue(symbol.name, isCrossingInlineBounds)
symbol.hasDelegate -> CodeFragmentCapturedValue.LocalDelegate(symbol.name, symbol.isMutated, isCrossingInlineBounds)
else -> CodeFragmentCapturedValue.Local(symbol.name, symbol.isMutated, isCrossingInlineBounds)
}
@@ -37,7 +37,10 @@ val FirSession.codeFragmentScopeProvider: CodeFragmentScopeProvider by FirSessio
private object ForeignValueMarkerDataKey : FirDeclarationDataKey()
var FirProperty.foreignValueMarker: Boolean? by FirDeclarationDataRegistry.data(ForeignValueMarkerDataKey)
private var FirProperty.foreignValueMarker: Boolean? by FirDeclarationDataRegistry.data(ForeignValueMarkerDataKey)
val FirPropertySymbol.isForeignValue: Boolean
get() = fir.foreignValueMarker == true
class CodeFragmentScopeProvider(private val session: FirSession) : FirSessionComponent {
private val foreignValueProvider = ForeignValueProviderService.getInstance()