fixup! [Analysis API FIR] Initialize properties of `KtCallableSignature` lazily
diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10FunctionLikeSignature.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10FunctionLikeSignature.kt
index e97e119..ff3b76c 100644
--- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10FunctionLikeSignature.kt
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10FunctionLikeSignature.kt
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.signatures
+import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature
import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature
@@ -14,11 +15,15 @@
import org.jetbrains.kotlin.analysis.api.types.KtType
internal class KtFe10FunctionLikeSignature<out S : KtFunctionLikeSymbol>(
- symbol: S,
+ private val _symbol: S,
private val _returnType: KtType,
private val _receiverType: KtType?,
private val _valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>>,
-) : KtFunctionLikeSignature<S>(symbol) {
+) : KtFunctionLikeSignature<S>() {
+ override val token: KtLifetimeToken
+ get() = _symbol.token
+ override val symbol: S
+ get() = withValidityAssertion { _symbol }
override val returnType: KtType
get() = withValidityAssertion { _returnType }
override val receiverType: KtType?
@@ -26,16 +31,18 @@
override val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>>
get() = withValidityAssertion { _valueParameters }
- override fun substitute(substitutor: KtSubstitutor): KtFunctionLikeSignature<S> = KtFe10FunctionLikeSignature(
- symbol,
- substitutor.substitute(returnType),
- receiverType?.let { substitutor.substitute(it) },
- valueParameters.map { valueParameter ->
- KtFe10VariableLikeSignature<KtValueParameterSymbol>(
- valueParameter.symbol,
- substitutor.substitute(valueParameter.returnType),
- valueParameter.receiverType?.let { substitutor.substitute(it) }
- )
- }
- )
+ override fun substitute(substitutor: KtSubstitutor): KtFunctionLikeSignature<S> = withValidityAssertion {
+ KtFe10FunctionLikeSignature(
+ symbol,
+ substitutor.substitute(returnType),
+ receiverType?.let { substitutor.substitute(it) },
+ valueParameters.map { valueParameter ->
+ KtFe10VariableLikeSignature<KtValueParameterSymbol>(
+ valueParameter.symbol,
+ substitutor.substitute(valueParameter.returnType),
+ valueParameter.receiverType?.let { substitutor.substitute(it) }
+ )
+ }
+ )
+ }
}
diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10VariableLikeSignature.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10VariableLikeSignature.kt
index 539377e..509af9f 100644
--- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10VariableLikeSignature.kt
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10VariableLikeSignature.kt
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.signatures
+import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
@@ -12,18 +13,24 @@
import org.jetbrains.kotlin.analysis.api.types.KtType
internal class KtFe10VariableLikeSignature<out S : KtVariableLikeSymbol>(
- symbol: S,
+ private val _symbol: S,
private val _returnType: KtType,
private val _receiverType: KtType?,
-) : KtVariableLikeSignature<S>(symbol) {
+) : KtVariableLikeSignature<S>() {
+ override val token: KtLifetimeToken
+ get() = _symbol.token
+ override val symbol: S
+ get() = withValidityAssertion { _symbol }
override val returnType: KtType
get() = withValidityAssertion { _returnType }
override val receiverType: KtType?
get() = withValidityAssertion { _receiverType }
- override fun substitute(substitutor: KtSubstitutor): KtVariableLikeSignature<S> = KtFe10VariableLikeSignature(
- symbol,
- substitutor.substitute(returnType),
- receiverType?.let { substitutor.substitute(it) },
- )
+ override fun substitute(substitutor: KtSubstitutor): KtVariableLikeSignature<S> = withValidityAssertion {
+ KtFe10VariableLikeSignature(
+ symbol,
+ substitutor.substitute(returnType),
+ receiverType?.let { substitutor.substitute(it) },
+ )
+ }
}
\ No newline at end of file
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 5ff2490..a9a187b 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
@@ -63,8 +63,8 @@
import org.jetbrains.kotlin.types.Variance
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
-import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirFunctionFirSymbolBasedSignature
-import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirPropertyFirSymbolBasedSignature
+import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirFunctionLikeSubstitutorBasedSignature
+import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirVariableLikeSubstitutorBasedSignature
/**
* Maps FirElement to KtSymbol & ConeType to KtType, thread safe
@@ -222,8 +222,7 @@
fun buildFunctionSignature(firSymbol: FirNamedFunctionSymbol): KtFunctionLikeSignature<KtFirFunctionSymbol> {
firSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
- val functionSymbol = buildFunctionSymbol(firSymbol)
- return KtFirFunctionFirSymbolBasedSignature(functionSymbol, firSymbol, analysisSession.firSymbolBuilder)
+ return KtFirFunctionLikeSubstitutorBasedSignature(analysisSession.token, firSymbol, analysisSession.firSymbolBuilder)
}
fun buildAnonymousFunctionSymbol(firSymbol: FirAnonymousFunctionSymbol): KtFirAnonymousFunctionSymbol {
@@ -303,7 +302,7 @@
fun buildPropertySignature(firSymbol: FirPropertySymbol): KtVariableLikeSignature<KtVariableSymbol> {
firSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
- return KtFirPropertyFirSymbolBasedSignature(buildPropertySymbol(firSymbol), firSymbol, analysisSession.firSymbolBuilder)
+ return KtFirVariableLikeSubstitutorBasedSignature(analysisSession.token, firSymbol, analysisSession.firSymbolBuilder)
}
fun buildLocalVariableSymbol(firSymbol: FirPropertySymbol): KtFirLocalVariableSymbol {
@@ -320,6 +319,9 @@
}
fun buildValueParameterSymbol(firSymbol: FirValueParameterSymbol): KtValueParameterSymbol {
+ firSymbol.fir.unwrapSubstitutionOverrideIfNeeded()?.let {
+ return buildValueParameterSymbol(it.symbol)
+ }
return symbolsCache.cache(firSymbol) {
KtFirValueParameterSymbol(firSymbol, analysisSession)
}
@@ -511,8 +513,8 @@
private inline fun <reified T : FirCallableDeclaration> T.unwrapUseSiteSubstitutionOverride(): T? {
val originalDeclaration = originalForSubstitutionOverride ?: return null
- val containingClass = getContainingClass(rootSession) ?: return null
- val originalContainingClass = originalDeclaration.getContainingClass(rootSession) ?: return null
+ val containingClass = getContainingMemberOrSelf().getContainingClass(rootSession) ?: return null
+ val originalContainingClass = originalDeclaration.getContainingMemberOrSelf().getContainingClass(rootSession) ?: return null
// If substitution override does not change the containing class of the FIR declaration,
// it is a use-site substitution override
@@ -521,6 +523,11 @@
return originalDeclaration
}
+ private fun FirCallableDeclaration.getContainingMemberOrSelf(): FirCallableDeclaration = when (this) {
+ is FirValueParameter -> containingFunctionSymbol.fir
+ else -> this
+ }
+
/**
* We want to unwrap a SUBSTITUTION_OVERRIDE wrapper if it doesn't affect the declaration's signature in any way. If the signature
* is somehow changed, then we want to keep the wrapper.
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSignatureSubstitutor.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSignatureSubstitutor.kt
index 4876038..8584e04 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSignatureSubstitutor.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSignatureSubstitutor.kt
@@ -6,20 +6,27 @@
package org.jetbrains.kotlin.analysis.api.fir.components
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
-import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirFunctionLikeSymbolBasedSignature
-import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirVariableLikeSymbolBasedSignature
+import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirFunctionLikeDummySignature
+import org.jetbrains.kotlin.analysis.api.fir.signatures.KtFirVariableLikeDummySignature
+import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
import org.jetbrains.kotlin.analysis.api.impl.base.components.AbstractKtSignatureSubstitutor
import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature
import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
internal class KtFirSignatureSubstitutor(
override val analysisSession: KtFirAnalysisSession
) : AbstractKtSignatureSubstitutor(), KtFirAnalysisSessionComponent {
- override fun <S : KtFunctionLikeSymbol> asSignature(symbol: S): KtFunctionLikeSignature<S> =
- KtFirFunctionLikeSymbolBasedSignature<S>(symbol)
+ override fun <S : KtFunctionLikeSymbol> asSignature(symbol: S): KtFunctionLikeSignature<S> {
+ val firSymbol = (symbol as KtFirSymbol<*>).firSymbol as FirFunctionSymbol<*>
+ return KtFirFunctionLikeDummySignature<S>(analysisSession.token, firSymbol, analysisSession.firSymbolBuilder)
+ }
- override fun <S : KtVariableLikeSymbol> asSignature(symbol: S): KtVariableLikeSignature<S> =
- KtFirVariableLikeSymbolBasedSignature<S>(symbol)
+ override fun <S : KtVariableLikeSymbol> asSignature(symbol: S): KtVariableLikeSignature<S> {
+ val firSymbol = (symbol as KtFirSymbol<*>).firSymbol as FirVariableSymbol<*>
+ return KtFirVariableLikeDummySignature<S>(analysisSession.token, firSymbol, analysisSession.firSymbolBuilder)
+ }
}
\ No newline at end of file
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/FirSymbolBasedSignature.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/FirSymbolBasedSignature.kt
index a4efa4f..96ecfc6 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/FirSymbolBasedSignature.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/FirSymbolBasedSignature.kt
@@ -6,8 +6,9 @@
package org.jetbrains.kotlin.analysis.api.fir.signatures
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
+import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
-internal interface FirSymbolBasedSignature<S> {
- val firSymbol: S
+internal interface FirSymbolBasedSignature {
+ val firSymbol: FirCallableSymbol<*>
val firSymbolBuilder: KtSymbolByFirBuilder
}
\ No newline at end of file
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirFunctionLikeSignature.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirFunctionLikeSignature.kt
index 95de238..3dedb27 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirFunctionLikeSignature.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirFunctionLikeSignature.kt
@@ -6,67 +6,82 @@
package org.jetbrains.kotlin.analysis.api.fir.signatures
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
-import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFunctionSymbol
+import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
+import org.jetbrains.kotlin.analysis.api.fir.types.AbstractKtFirSubstitutor
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
-import org.jetbrains.kotlin.analysis.api.impl.base.types.KtChainedSubstitutor
+import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
+import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature
import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
+import org.jetbrains.kotlin.analysis.api.symbols.receiverType
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
-import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
+import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
+import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
+import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
+import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
-internal sealed class KtFirFunctionLikeSignature<out S : KtFunctionLikeSymbol>(ktSymbol: S) : KtFunctionLikeSignature<S>(ktSymbol) {
+internal sealed class KtFirFunctionLikeSignature<out S : KtFunctionLikeSymbol> : KtFunctionLikeSignature<S>(), FirSymbolBasedSignature {
abstract override fun substitute(substitutor: KtSubstitutor): KtFirFunctionLikeSignature<S>
}
-internal class KtFirFunctionLikeSubstitutorBasedSignature<out S : KtFunctionLikeSymbol>(
- override val signature: KtFunctionLikeSignature<S>,
- override val substitutor: KtSubstitutor,
-) : KtFirFunctionLikeSignature<S>(signature.symbol), SubstitutorBasedSignature<KtFunctionLikeSignature<S>> {
- override val returnType: KtType by cached {
- substitutor.substitute(signature.returnType)
- }
- override val receiverType: KtType? by cached {
- signature.receiverType?.let { substitutor.substitute(it) }
- }
- override val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>> by cached {
- signature.valueParameters.map { it.substitute(substitutor) }
- }
-
- override fun substitute(substitutor: KtSubstitutor): KtFirFunctionLikeSignature<S> = when {
- substitutor is KtSubstitutor.Empty -> this
- else -> KtFirFunctionLikeSubstitutorBasedSignature(signature, KtChainedSubstitutor(this.substitutor, substitutor))
- }
-}
-
-internal open class KtFirFunctionLikeSymbolBasedSignature<S : KtFunctionLikeSymbol>(ktSymbol: S) : KtFirFunctionLikeSignature<S>(ktSymbol) {
- override val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>> by cached {
- ktSymbol.valueParameters.map { KtFirVariableLikeSymbolBasedSignature(it) }
- }
-
- override fun substitute(substitutor: KtSubstitutor): KtFirFunctionLikeSignature<S> = when {
- substitutor is KtSubstitutor.Empty -> this
- else -> KtFirFunctionLikeSubstitutorBasedSignature(this, substitutor)
- }
-}
-
-internal class KtFirFunctionFirSymbolBasedSignature(
- ktSymbol: KtFirFunctionSymbol,
- override val firSymbol: FirNamedFunctionSymbol,
+internal class KtFirFunctionLikeDummySignature<out S : KtFunctionLikeSymbol>(
+ override val token: KtLifetimeToken,
+ override val firSymbol: FirFunctionSymbol<*>,
override val firSymbolBuilder: KtSymbolByFirBuilder,
-) : KtFirFunctionLikeSymbolBasedSignature<KtFirFunctionSymbol>(ktSymbol), FirSymbolBasedSignature<FirNamedFunctionSymbol> {
+) : KtFirFunctionLikeSignature<S>() {
+ @Suppress("UNCHECKED_CAST")
+ override val symbol: S
+ get() = withValidityAssertion { firSymbol.buildSymbol(firSymbolBuilder) as S }
+ override val returnType: KtType
+ get() = withValidityAssertion { symbol.returnType }
+ override val receiverType: KtType?
+ get() = withValidityAssertion { symbol.receiverType }
+ override val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>> by cached {
+ firSymbol.valueParameterSymbols.map { KtFirVariableLikeDummySignature(token, it, firSymbolBuilder) }
+ }
+
+ override fun substitute(substitutor: KtSubstitutor): KtFirFunctionLikeSignature<S> = withValidityAssertion {
+ if (substitutor is KtSubstitutor.Empty) return@withValidityAssertion this
+ require(substitutor is AbstractKtFirSubstitutor<*>)
+
+ KtFirFunctionLikeSubstitutorBasedSignature(token, firSymbol, firSymbolBuilder, substitutor.substitutor)
+ }
+}
+
+internal class KtFirFunctionLikeSubstitutorBasedSignature<out S : KtFunctionLikeSymbol>(
+ override val token: KtLifetimeToken,
+ override val firSymbol: FirFunctionSymbol<*>,
+ override val firSymbolBuilder: KtSymbolByFirBuilder,
+ override val coneSubstitutor: ConeSubstitutor = ConeSubstitutor.Empty,
+) : KtFirFunctionLikeSignature<S>(), SubstitutorBasedSignature {
+ @Suppress("UNCHECKED_CAST")
+ override val symbol: S
+ get() = withValidityAssertion { firSymbol.buildSymbol(firSymbolBuilder) as S }
override val returnType: KtType by cached {
- firSymbolBuilder.typeBuilder.buildKtType(firSymbol.resolvedReturnType)
+ firSymbolBuilder.typeBuilder.buildKtType(coneSubstitutor.substituteOrSelf(firSymbol.resolvedReturnType))
}
override val receiverType: KtType? by cached {
- firSymbol.resolvedReceiverTypeRef?.let { firSymbolBuilder.typeBuilder.buildKtType(it) }
+ val receiverTypeRef = when (val fir = firSymbol.fir) {
+ is FirPropertyAccessor -> fir.propertySymbol.resolvedReceiverTypeRef
+ else -> firSymbol.resolvedReceiverTypeRef
+ }
+ receiverTypeRef?.let { firSymbolBuilder.typeBuilder.buildKtType(coneSubstitutor.substituteOrSelf(it.type)) }
}
override val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>> by cached {
- ktSymbol.valueParameters.zip(firSymbol.fir.valueParameters).map { (ktValueParameterSymbol, firValueParameter) ->
- KtFirValueParameterFirSymbolBasedSignature(ktValueParameterSymbol, firValueParameter.symbol, firSymbolBuilder)
+ firSymbol.fir.valueParameters.map { firValueParameter ->
+ KtFirVariableLikeSubstitutorBasedSignature(token, firValueParameter.symbol, firSymbolBuilder, coneSubstitutor)
}
}
+
+ override fun substitute(substitutor: KtSubstitutor): KtFirFunctionLikeSignature<S> = withValidityAssertion {
+ if (substitutor is KtSubstitutor.Empty) return@withValidityAssertion this
+ require(substitutor is AbstractKtFirSubstitutor<*>)
+ val chainedSubstitutor = ChainedSubstitutor(coneSubstitutor, substitutor.substitutor)
+
+ KtFirFunctionLikeSubstitutorBasedSignature(token, firSymbol, firSymbolBuilder, chainedSubstitutor)
+ }
}
\ No newline at end of file
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirVariableLikeSignature.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirVariableLikeSignature.kt
index 57fc955..9ebe829 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirVariableLikeSignature.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirVariableLikeSignature.kt
@@ -6,76 +6,75 @@
package org.jetbrains.kotlin.analysis.api.fir.signatures
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
+import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
+import org.jetbrains.kotlin.analysis.api.fir.types.AbstractKtFirSubstitutor
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
-import org.jetbrains.kotlin.analysis.api.impl.base.types.KtChainedSubstitutor
+import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature
-import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
-import org.jetbrains.kotlin.analysis.api.symbols.KtVariableSymbol
+import org.jetbrains.kotlin.analysis.api.symbols.receiverType
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
-import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
+import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
+import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.arrayElementType
import org.jetbrains.kotlin.fir.types.coneType
+import org.jetbrains.kotlin.utils.addToStdlib.applyIf
-internal sealed class KtFirVariableLikeSignature<out S : KtVariableLikeSymbol>(ktSymbol: S) : KtVariableLikeSignature<S>(ktSymbol) {
+internal sealed class KtFirVariableLikeSignature<out S : KtVariableLikeSymbol> : KtVariableLikeSignature<S>(), FirSymbolBasedSignature {
abstract override fun substitute(substitutor: KtSubstitutor): KtFirVariableLikeSignature<S>
}
-internal class KtFirVariableLikeSubstitutorBasedSignature<out S : KtVariableLikeSymbol>(
- override val signature: KtVariableLikeSignature<S>,
- override val substitutor: KtSubstitutor,
-) : KtFirVariableLikeSignature<S>(signature.symbol), SubstitutorBasedSignature<KtVariableLikeSignature<S>> {
- override val returnType: KtType by cached {
- substitutor.substitute(signature.returnType)
- }
- override val receiverType: KtType? by cached {
- signature.receiverType?.let { substitutor.substitute(it) }
- }
-
- override fun substitute(substitutor: KtSubstitutor): KtFirVariableLikeSignature<S> = when {
- substitutor is KtSubstitutor.Empty -> this
- else -> KtFirVariableLikeSubstitutorBasedSignature(signature, KtChainedSubstitutor(this.substitutor, substitutor))
- }
-}
-
-internal open class KtFirVariableLikeSymbolBasedSignature<out S : KtVariableLikeSymbol>(
- ktSymbol: S
-) : KtFirVariableLikeSignature<S>(ktSymbol) {
- override fun substitute(substitutor: KtSubstitutor): KtFirVariableLikeSignature<S> = when {
- substitutor is KtSubstitutor.Empty -> this
- else -> KtFirVariableLikeSubstitutorBasedSignature(this, substitutor)
- }
-}
-
-internal class KtFirPropertyFirSymbolBasedSignature(
- ktSymbol: KtVariableSymbol,
- override val firSymbol: FirPropertySymbol,
+internal class KtFirVariableLikeDummySignature<out S : KtVariableLikeSymbol>(
+ override val token: KtLifetimeToken,
+ override val firSymbol: FirVariableSymbol<*>,
override val firSymbolBuilder: KtSymbolByFirBuilder,
-) : KtFirVariableLikeSymbolBasedSignature<KtVariableSymbol>(ktSymbol), FirSymbolBasedSignature<FirPropertySymbol> {
+) : KtFirVariableLikeSignature<S>() {
+ @Suppress("UNCHECKED_CAST")
+ override val symbol: S
+ get() = withValidityAssertion { firSymbol.buildSymbol(firSymbolBuilder) as S }
+ override val returnType: KtType
+ get() = withValidityAssertion { symbol.returnType }
+ override val receiverType: KtType?
+ get() = withValidityAssertion { symbol.receiverType }
+
+ override fun substitute(substitutor: KtSubstitutor): KtFirVariableLikeSignature<S> = withValidityAssertion {
+ if (substitutor is KtSubstitutor.Empty) return@withValidityAssertion this
+ require(substitutor is AbstractKtFirSubstitutor<*>)
+
+ KtFirVariableLikeSubstitutorBasedSignature(token, firSymbol, firSymbolBuilder, substitutor.substitutor)
+ }
+}
+
+internal class KtFirVariableLikeSubstitutorBasedSignature<out S : KtVariableLikeSymbol>(
+ override val token: KtLifetimeToken,
+ override val firSymbol: FirVariableSymbol<*>,
+ override val firSymbolBuilder: KtSymbolByFirBuilder,
+ override val coneSubstitutor: ConeSubstitutor = ConeSubstitutor.Empty,
+) : KtFirVariableLikeSignature<S>(), SubstitutorBasedSignature {
+ @Suppress("UNCHECKED_CAST")
+ override val symbol: S
+ get() = withValidityAssertion { firSymbol.buildSymbol(firSymbolBuilder) as S }
override val returnType: KtType by cached {
- firSymbolBuilder.typeBuilder.buildKtType(firSymbol.resolvedReturnType)
+ val isVarargValueParameter = (firSymbol as? FirValueParameterSymbol)?.isVararg == true
+ val coneType = firSymbol.resolvedReturnType.applyIf(isVarargValueParameter) { arrayElementType() ?: this }
+
+ firSymbolBuilder.typeBuilder.buildKtType(coneSubstitutor.substituteOrSelf(coneType))
}
override val receiverType: KtType? by cached {
firSymbol.resolvedReceiverTypeRef?.let { typeRef ->
- firSymbolBuilder.typeBuilder.buildKtType(typeRef.coneType)
+ firSymbolBuilder.typeBuilder.buildKtType(coneSubstitutor.substituteOrSelf(typeRef.coneType))
}
}
-}
-internal class KtFirValueParameterFirSymbolBasedSignature(
- ktSymbol: KtValueParameterSymbol,
- override val firSymbol: FirValueParameterSymbol,
- override val firSymbolBuilder: KtSymbolByFirBuilder,
-) : KtFirVariableLikeSymbolBasedSignature<KtValueParameterSymbol>(ktSymbol), FirSymbolBasedSignature<FirValueParameterSymbol> {
- override val returnType: KtType by cached {
- var coneType = firSymbol.resolvedReturnType
- if (firSymbol.isVararg) {
- coneType = coneType.arrayElementType() ?: coneType
- }
- firSymbolBuilder.typeBuilder.buildKtType(coneType)
+ override fun substitute(substitutor: KtSubstitutor): KtFirVariableLikeSignature<S> = withValidityAssertion {
+ if (substitutor is KtSubstitutor.Empty) return@withValidityAssertion this
+ require(substitutor is AbstractKtFirSubstitutor<*>)
+ val chainedSubstitutor = ChainedSubstitutor(coneSubstitutor, substitutor.substitutor)
+
+ KtFirVariableLikeSubstitutorBasedSignature(token, firSymbol, firSymbolBuilder, chainedSubstitutor)
}
- override val receiverType: KtType? get() = withValidityAssertion { null }
}
\ No newline at end of file
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/SubstitutorBasedSignature.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/SubstitutorBasedSignature.kt
index d498e91..f10c651 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/SubstitutorBasedSignature.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/SubstitutorBasedSignature.kt
@@ -5,10 +5,8 @@
package org.jetbrains.kotlin.analysis.api.fir.signatures
-import org.jetbrains.kotlin.analysis.api.signatures.KtCallableSignature
-import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
+import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
-interface SubstitutorBasedSignature<out S : KtCallableSignature<*>> {
- val signature: S
- val substitutor: KtSubstitutor
+internal interface SubstitutorBasedSignature {
+ val coneSubstitutor: ConeSubstitutor
}
\ No newline at end of file
diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/types/KtChainedSubstitutor.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/types/KtChainedSubstitutor.kt
deleted file mode 100644
index fc30224..0000000
--- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/types/KtChainedSubstitutor.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * 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.types
-
-import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
-import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
-import org.jetbrains.kotlin.analysis.api.types.KtType
-
-class KtChainedSubstitutor(val first: KtSubstitutor, val second: KtSubstitutor) : KtSubstitutor {
- override val token: KtLifetimeToken get() = first.token
- override fun substituteOrNull(type: KtType): KtType? = first.substituteOrNull(type)?.let { second.substituteOrNull(it) }
-}
\ No newline at end of file
diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt
index 0b240ac..3750aad 100644
--- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt
+++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/testUtils.kt
@@ -33,12 +33,6 @@
@OptIn(KtAnalysisApiInternals::class)
internal fun KtAnalysisSession.stringRepresentation(any: Any): String = with(any) {
fun KtType.render() = asStringForDebugging().replace('/', '.')
- fun String.indented() = replace("\n", "\n ")
- fun Any.clazz() = when (this) {
- is KtVariableLikeSignature<*> -> KtVariableLikeSignature::class
- is KtFunctionLikeSignature<*> -> KtFunctionLikeSignature::class
- else -> this::class
- }
return when (this) {
is KtFunctionLikeSymbol -> buildString {
append(
@@ -96,8 +90,9 @@
is Enum<*> -> name
is Name -> asString()
is CallableId -> toString()
+ is KtCallableSignature<*> -> this.stringRepresentation()
else -> buildString {
- val clazz = this@with.clazz()
+ val clazz = this@with::class
val className = clazz.simpleName!!
append(className)
appendLine(":")
@@ -119,6 +114,31 @@
}
}
+context(KtAnalysisSession)
+private fun KtCallableSignature<*>.stringRepresentation(): String = buildString {
+ when (this@stringRepresentation) {
+ is KtFunctionLikeSignature<*> -> append(KtFunctionLikeSignature::class.simpleName)
+ is KtVariableLikeSignature<*> -> append(KtVariableLikeSignature::class.simpleName)
+ }
+ appendLine(":")
+ val memberProperties = listOfNotNull(
+ KtVariableLikeSignature<*>::name.takeIf { this@stringRepresentation is KtVariableLikeSignature<*> },
+ KtCallableSignature<*>::receiverType,
+ KtCallableSignature<*>::returnType,
+ KtCallableSignature<*>::symbol,
+ KtFunctionLikeSignature<*>::valueParameters.takeIf { this@stringRepresentation is KtFunctionLikeSignature<*> },
+ KtCallableSignature<*>::callableIdIfNonLocal
+ )
+ memberProperties.joinTo(this, separator = "\n ", prefix = " ") { property ->
+ @Suppress("UNCHECKED_CAST")
+ val value = (property as KProperty1<Any, *>).get(this@stringRepresentation)
+ val valueAsString = value?.let { stringRepresentation(it).indented() }
+ "${property.name} = $valueAsString"
+ }
+}
+
+private fun String.indented() = replace("\n", "\n ")
+
internal fun KtAnalysisSession.prettyPrintSignature(signature: KtCallableSignature<*>): String = prettyPrint {
when (signature) {
is KtFunctionLikeSignature -> {
diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtFunctionLikeSignature.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtFunctionLikeSignature.kt
index 94c4949..1e7421e 100644
--- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtFunctionLikeSignature.kt
+++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtFunctionLikeSignature.kt
@@ -5,29 +5,15 @@
package org.jetbrains.kotlin.analysis.api.signatures
-import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
-import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
-import org.jetbrains.kotlin.analysis.api.symbols.receiverType
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
/**
* A signature of a function-like symbol. This includes functions, getters, setters, lambdas, etc.
*/
-public abstract class KtFunctionLikeSignature<out S : KtFunctionLikeSymbol>(
- private val _symbol: S
-) : KtCallableSignature<S>() {
- override val token: KtLifetimeToken
- get() = _symbol.token
- override val symbol: S
- get() = withValidityAssertion { _symbol }
- override val returnType: KtType
- get() = withValidityAssertion { _symbol.returnType }
- override val receiverType: KtType?
- get() = withValidityAssertion { _symbol.receiverType }
-
+public abstract class KtFunctionLikeSignature<out S : KtFunctionLikeSymbol> : KtCallableSignature<S>() {
/**
* The use-site-substituted value parameters.
*/
diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtVariableLikeSignature.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtVariableLikeSignature.kt
index e7b405a..10f3be4 100644
--- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtVariableLikeSignature.kt
+++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtVariableLikeSignature.kt
@@ -8,10 +8,8 @@
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationWithArgumentsInfo
import org.jetbrains.kotlin.analysis.api.annotations.KtConstantAnnotationValue
import org.jetbrains.kotlin.analysis.api.annotations.annotationsByClassId
-import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
-import org.jetbrains.kotlin.analysis.api.symbols.receiverType
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.builtins.StandardNames
@@ -23,18 +21,7 @@
/**
* A signature of a variable-like symbol. This includes properties, enum entries local variables, etc.
*/
-public abstract class KtVariableLikeSignature<out S : KtVariableLikeSymbol>(
- private val _symbol: S,
-) : KtCallableSignature<S>() {
- override val token: KtLifetimeToken
- get() = _symbol.token
- override val symbol: S
- get() = withValidityAssertion { _symbol }
- override val returnType: KtType
- get() = withValidityAssertion { _symbol.returnType }
- override val receiverType: KtType?
- get() = withValidityAssertion { _symbol.receiverType }
-
+public abstract class KtVariableLikeSignature<out S : KtVariableLikeSymbol> : KtCallableSignature<S>() {
/**
* A name of the variable with respect to the `@ParameterName` annotation. Can be different from the [KtVariableLikeSymbol.name].
*