[Analysis API FIR] Initialize properties of `KtCallableSignature` lazily
diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt
index 01053b6..8812364 100644
--- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10CallResolver.kt
@@ -10,6 +10,8 @@
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
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.signatures.KtFe10FunctionLikeSignature
+import org.jetbrains.kotlin.analysis.api.descriptors.signatures.KtFe10VariableLikeSignature
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.KtFe10DescValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.KtFe10ReceiverParameterSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.KtFe10DescSymbol
@@ -59,10 +61,6 @@
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.UnwrappedType
-import org.jetbrains.kotlin.types.asSimpleType
-import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext.contains
-import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext.isTypeVariable
-import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext.typeConstructor
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -567,8 +565,8 @@
resultingDescriptor.extensionReceiverParameter?.returnType?.toKtType(analysisContext)
}
return when (symbol) {
- is KtVariableLikeSymbol -> KtVariableLikeSignature(symbol, ktReturnType, receiverType)
- is KtFunctionLikeSymbol -> KtFunctionLikeSignature(
+ is KtVariableLikeSymbol -> KtFe10VariableLikeSignature(symbol, ktReturnType, receiverType)
+ is KtFunctionLikeSymbol -> KtFe10FunctionLikeSignature(
symbol,
ktReturnType,
receiverType,
diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SignatureSubstitutor.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SignatureSubstitutor.kt
index 5aa2977..c550c2c 100644
--- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SignatureSubstitutor.kt
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SignatureSubstitutor.kt
@@ -7,8 +7,23 @@
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent
-import org.jetbrains.kotlin.analysis.api.impl.base.components.AbstractKtSignatureSubstitutorImpl
+import org.jetbrains.kotlin.analysis.api.descriptors.signatures.KtFe10FunctionLikeSignature
+import org.jetbrains.kotlin.analysis.api.descriptors.signatures.KtFe10VariableLikeSignature
+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.analysis.api.symbols.receiverType
internal class KtFe10SignatureSubstitutor(
override val analysisSession: KtFe10AnalysisSession
-) : AbstractKtSignatureSubstitutorImpl(), Fe10KtAnalysisSessionComponent
\ No newline at end of file
+) : AbstractKtSignatureSubstitutor(), Fe10KtAnalysisSessionComponent {
+ override fun <S : KtFunctionLikeSymbol> asSignature(symbol: S): KtFunctionLikeSignature<S> {
+ return KtFe10FunctionLikeSignature(symbol, symbol.returnType, symbol.receiverType, symbol.valueParameters.map { asSignature(it) })
+ }
+
+ override fun <S : KtVariableLikeSymbol> asSignature(symbol: S): KtVariableLikeSignature<S> {
+ return KtFe10VariableLikeSignature(symbol, symbol.returnType, symbol.receiverType)
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..5789ee7
--- /dev/null
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10FunctionLikeSignature.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.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
+import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
+import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
+import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
+import org.jetbrains.kotlin.analysis.api.types.KtType
+
+internal class KtFe10FunctionLikeSignature<out S : KtFunctionLikeSymbol>(
+ private val _symbol: S,
+ private val _returnType: KtType,
+ private val _receiverType: KtType?,
+ private val _valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>>,
+) : 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?
+ get() = withValidityAssertion { _receiverType }
+ override val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>>
+ get() = withValidityAssertion { _valueParameters }
+
+ 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) }
+ )
+ }
+ )
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as KtFunctionLikeSignature<*>
+
+ if (symbol != other.symbol) return false
+ if (returnType != other.returnType) return false
+ if (receiverType != other.receiverType) return false
+ if (valueParameters != other.valueParameters) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = symbol.hashCode()
+ result = 31 * result + returnType.hashCode()
+ result = 31 * result + (receiverType?.hashCode() ?: 0)
+ result = 31 * result + valueParameters.hashCode()
+ return result
+ }
+}
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
new file mode 100644
index 0000000..4d615c8
--- /dev/null
+++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/signatures/KtFe10VariableLikeSignature.kt
@@ -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.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
+import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
+import org.jetbrains.kotlin.analysis.api.types.KtType
+
+internal class KtFe10VariableLikeSignature<out S : KtVariableLikeSymbol>(
+ private val _symbol: S,
+ private val _returnType: KtType,
+ private val _receiverType: KtType?,
+) : 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> = withValidityAssertion {
+ KtFe10VariableLikeSignature(
+ symbol,
+ substitutor.substitute(returnType),
+ receiverType?.let { substitutor.substitute(it) },
+ )
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as KtVariableLikeSignature<*>
+
+ if (symbol != other.symbol) return false
+ if (returnType != other.returnType) return false
+ if (receiverType != other.receiverType) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = symbol.hashCode()
+ result = 31 * result + returnType.hashCode()
+ result = 31 * result + (receiverType?.hashCode() ?: 0)
+ return result
+ }
+}
\ 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 572c4c9..ea26b2d 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
@@ -62,6 +62,8 @@
import org.jetbrains.kotlin.types.Variance
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
+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
@@ -219,19 +221,7 @@
fun buildFunctionSignature(firSymbol: FirNamedFunctionSymbol): KtFunctionLikeSignature<KtFirFunctionSymbol> {
firSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
- val functionSymbol = buildFunctionSymbol(firSymbol)
- return KtFunctionLikeSignature(
- functionSymbol,
- typeBuilder.buildKtType(firSymbol.resolvedReturnType),
- firSymbol.resolvedReceiverTypeRef?.let { typeBuilder.buildKtType(it) },
- functionSymbol.valueParameters.zip(firSymbol.fir.valueParameters).map { (ktSymbol, fir) ->
- var type = fir.returnTypeRef.coneType
- if (fir.isVararg) {
- type = type.arrayElementType() ?: type
- }
- KtVariableLikeSignature(ktSymbol, typeBuilder.buildKtType(type), null)
- }
- )
+ return KtFirFunctionLikeSubstitutorBasedSignature(analysisSession.token, firSymbol, analysisSession.firSymbolBuilder)
}
fun buildAnonymousFunctionSymbol(firSymbol: FirAnonymousFunctionSymbol): KtFirAnonymousFunctionSymbol {
@@ -311,11 +301,7 @@
fun buildPropertySignature(firSymbol: FirPropertySymbol): KtVariableLikeSignature<KtVariableSymbol> {
firSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
- return KtVariableLikeSignature(
- buildPropertySymbol(firSymbol),
- typeBuilder.buildKtType(firSymbol.fir.returnTypeRef),
- firSymbol.resolvedReceiverTypeRef?.let { typeBuilder.buildKtType(it) }
- )
+ return KtFirVariableLikeSubstitutorBasedSignature(analysisSession.token, firSymbol, analysisSession.firSymbolBuilder)
}
fun buildLocalVariableSymbol(firSymbol: FirPropertySymbol): KtFirLocalVariableSymbol {
@@ -332,6 +318,9 @@
}
fun buildValueParameterSymbol(firSymbol: FirValueParameterSymbol): KtValueParameterSymbol {
+ firSymbol.fir.unwrapSubstitutionOverrideIfNeeded()?.let {
+ return buildValueParameterSymbol(it.symbol)
+ }
return symbolsCache.cache(firSymbol) {
KtFirValueParameterSymbol(firSymbol, analysisSession)
}
@@ -529,8 +518,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
@@ -539,6 +528,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 3615ea4..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,8 +6,27 @@
package org.jetbrains.kotlin.analysis.api.fir.components
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
-import org.jetbrains.kotlin.analysis.api.impl.base.components.AbstractKtSignatureSubstitutorImpl
+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
-) : AbstractKtSignatureSubstitutorImpl(), KtFirAnalysisSessionComponent
\ No newline at end of file
+) : AbstractKtSignatureSubstitutor(), KtFirAnalysisSessionComponent {
+ 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> {
+ 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
new file mode 100644
index 0000000..96ecfc6
--- /dev/null
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/FirSymbolBasedSignature.kt
@@ -0,0 +1,14 @@
+/*
+ * 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.fir.signatures
+
+import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
+import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
+
+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
new file mode 100644
index 0000000..097e0ed
--- /dev/null
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirFunctionLikeSignature.kt
@@ -0,0 +1,106 @@
+/*
+ * 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.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.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.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> : KtFunctionLikeSignature<S>(), FirSymbolBasedSignature {
+ abstract override fun substitute(substitutor: KtSubstitutor): KtFirFunctionLikeSignature<S>
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as KtFirFunctionLikeSignature<*>
+ return firSymbol == other.firSymbol
+ }
+
+ override fun hashCode(): Int = firSymbol.hashCode()
+}
+
+internal class KtFirFunctionLikeDummySignature<out S : KtFunctionLikeSymbol>(
+ override val token: KtLifetimeToken,
+ override val firSymbol: FirFunctionSymbol<*>,
+ override val firSymbolBuilder: KtSymbolByFirBuilder,
+) : 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(coneSubstitutor.substituteOrSelf(firSymbol.resolvedReturnType))
+ }
+ override val receiverType: KtType? by cached {
+ 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 {
+ 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)
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (!super.equals(other)) return false
+
+ other as KtFirFunctionLikeSubstitutorBasedSignature<*>
+ return coneSubstitutor == other.coneSubstitutor
+ }
+
+ override fun hashCode(): Int = 31 * super.hashCode() + coneSubstitutor.hashCode()
+}
\ 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
new file mode 100644
index 0000000..9d1a225
--- /dev/null
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/KtFirVariableLikeSignature.kt
@@ -0,0 +1,99 @@
+/*
+ * 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.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.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
+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.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> : KtVariableLikeSignature<S>(), FirSymbolBasedSignature {
+ abstract override fun substitute(substitutor: KtSubstitutor): KtFirVariableLikeSignature<S>
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as KtFirVariableLikeSignature<*>
+ return firSymbol == other.firSymbol
+ }
+
+ override fun hashCode(): Int = firSymbol.hashCode()
+}
+
+internal class KtFirVariableLikeDummySignature<out S : KtVariableLikeSymbol>(
+ override val token: KtLifetimeToken,
+ override val firSymbol: FirVariableSymbol<*>,
+ override val firSymbolBuilder: KtSymbolByFirBuilder,
+) : 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 {
+ 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(coneSubstitutor.substituteOrSelf(typeRef.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 fun equals(other: Any?): Boolean {
+ if (!super.equals(other)) return false
+
+ other as KtFirVariableLikeSubstitutorBasedSignature<*>
+ return coneSubstitutor == other.coneSubstitutor
+ }
+
+ override fun hashCode(): Int = 31 * super.hashCode() + coneSubstitutor.hashCode()
+}
\ 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
new file mode 100644
index 0000000..f10c651
--- /dev/null
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/signatures/SubstitutorBasedSignature.kt
@@ -0,0 +1,12 @@
+/*
+ * 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.fir.signatures
+
+import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
+
+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/components/AbstractKtSignatureSubstitutor.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtSignatureSubstitutor.kt
new file mode 100644
index 0000000..265719a
--- /dev/null
+++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtSignatureSubstitutor.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2022 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.components
+
+import org.jetbrains.kotlin.analysis.api.components.KtSignatureSubstitutor
+import org.jetbrains.kotlin.analysis.api.signatures.KtCallableSignature
+import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature
+import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature
+import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
+import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
+import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
+import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
+import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
+
+abstract class AbstractKtSignatureSubstitutor : KtSignatureSubstitutor() {
+ override fun <S : KtFunctionLikeSymbol> substitute(symbol: S, substitutor: KtSubstitutor): KtFunctionLikeSignature<S> {
+ if (substitutor is KtSubstitutor.Empty) return asSignature(symbol)
+ return asSignature(symbol).substitute(substitutor)
+ }
+
+ override fun <S : KtVariableLikeSymbol> substitute(symbol: S, substitutor: KtSubstitutor): KtVariableLikeSignature<S> {
+ if (substitutor is KtSubstitutor.Empty) return asSignature(symbol)
+ return asSignature(symbol).substitute(substitutor)
+ }
+
+ override fun <S : KtCallableSymbol> asSignature(symbol: S): KtCallableSignature<S> {
+ return when (symbol) {
+ is KtFunctionLikeSymbol -> asSignature(symbol)
+ is KtVariableLikeSymbol -> asSignature(symbol)
+ else -> unexpectedElementError("symbol", symbol)
+ }
+ }
+}
\ No newline at end of file
diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtSignatureSubstitutorImpl.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtSignatureSubstitutorImpl.kt
deleted file mode 100644
index 9a9cbeb..0000000
--- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/components/AbstractKtSignatureSubstitutorImpl.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2010-2022 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.components
-
-import org.jetbrains.kotlin.analysis.api.components.KtSignatureSubstitutor
-import org.jetbrains.kotlin.analysis.api.signatures.KtCallableSignature
-import org.jetbrains.kotlin.analysis.api.signatures.KtFunctionLikeSignature
-import org.jetbrains.kotlin.analysis.api.signatures.KtVariableLikeSignature
-import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
-import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
-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.utils.errors.unexpectedElementError
-
-abstract class AbstractKtSignatureSubstitutorImpl : KtSignatureSubstitutor() {
-
- override fun <S : KtVariableLikeSymbol> substitute(
- signature: KtVariableLikeSignature<S>,
- substitutor: KtSubstitutor
- ): KtVariableLikeSignature<S> {
- if (substitutor is KtSubstitutor.Empty) return signature
- return KtVariableLikeSignature(
- signature.symbol,
- substitutor.substitute(signature.returnType),
- signature.receiverType?.let { substitutor.substitute(it) },
- )
- }
-
- override fun <S : KtFunctionLikeSymbol> substitute(
- signature: KtFunctionLikeSignature<S>,
- substitutor: KtSubstitutor
- ): KtFunctionLikeSignature<S> {
- if (substitutor is KtSubstitutor.Empty) return signature
- return KtFunctionLikeSignature(
- signature.symbol,
- substitutor.substitute(signature.returnType),
- signature.receiverType?.let { substitutor.substitute(it) },
- signature.valueParameters.map { substitute(it, substitutor) }
- )
- }
-
- override fun <S : KtFunctionLikeSymbol> substitute(symbol: S, substitutor: KtSubstitutor): KtFunctionLikeSignature<S> {
- if (substitutor is KtSubstitutor.Empty) return asSignature(symbol)
- return KtFunctionLikeSignature(
- symbol,
- substitutor.substitute(symbol.returnType),
- symbol.receiverType?.let { substitutor.substitute(it) },
- symbol.valueParameters.map { substitute(it, substitutor) }
- )
- }
-
- override fun <S : KtVariableLikeSymbol> substitute(symbol: S, substitutor: KtSubstitutor): KtVariableLikeSignature<S> {
- if (substitutor is KtSubstitutor.Empty) return asSignature(symbol)
- return KtVariableLikeSignature(
- symbol,
- substitutor.substitute(symbol.returnType),
- symbol.receiverType?.let { substitutor.substitute(it) },
- )
- }
-
- override fun <S : KtCallableSymbol> asSignature(symbol: S): KtCallableSignature<S> {
- return when (symbol) {
- is KtFunctionLikeSymbol -> asSignature(symbol)
- is KtVariableLikeSymbol -> asSignature(symbol)
- else -> unexpectedElementError("symbol", symbol)
- }
- }
-
- override fun <S : KtFunctionLikeSymbol> asSignature(symbol: S): KtFunctionLikeSignature<S> {
- return KtFunctionLikeSignature(symbol, symbol.returnType, symbol.receiverType, symbol.valueParameters.map { asSignature(it) })
- }
-
- override fun <S : KtVariableLikeSymbol> asSignature(symbol: S): KtVariableLikeSignature<S> {
- return KtVariableLikeSignature(symbol, symbol.returnType, symbol.receiverType)
- }
-}
\ 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 bf40e44..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,7 +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 ")
return when (this) {
is KtFunctionLikeSymbol -> buildString {
append(
@@ -91,6 +90,7 @@
is Enum<*> -> name
is Name -> asString()
is CallableId -> toString()
+ is KtCallableSignature<*> -> this.stringRepresentation()
else -> buildString {
val clazz = this@with::class
val className = clazz.simpleName!!
@@ -114,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/components/KtSignatureSubstitutor.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSignatureSubstitutor.kt
index 5651597..36cca81 100644
--- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSignatureSubstitutor.kt
+++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSignatureSubstitutor.kt
@@ -16,31 +16,6 @@
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
public abstract class KtSignatureSubstitutor : KtAnalysisSessionComponent() {
- @Suppress("UNCHECKED_CAST")
- public open fun <S : KtCallableSymbol> substitute(
- signature: KtCallableSignature<S>,
- substitutor: KtSubstitutor
- ): KtCallableSignature<S> {
- return when (signature) {
- is KtFunctionLikeSignature -> {
- substitute(signature as KtFunctionLikeSignature<KtFunctionLikeSymbol>, substitutor) as KtCallableSignature<S>
- }
- is KtVariableLikeSignature -> {
- substitute(signature as KtVariableLikeSignature<KtVariableLikeSymbol>, substitutor) as KtCallableSignature<S>
- }
- }
- }
-
- public abstract fun <S : KtFunctionLikeSymbol> substitute(
- signature: KtFunctionLikeSignature<S>,
- substitutor: KtSubstitutor
- ): KtFunctionLikeSignature<S>
-
- public abstract fun <S : KtVariableLikeSymbol> substitute(
- signature: KtVariableLikeSignature<S>,
- substitutor: KtSubstitutor
- ): KtVariableLikeSignature<S>
-
public open fun <S : KtCallableSymbol> substitute(symbol: S, substitutor: KtSubstitutor): KtCallableSignature<S> = when (symbol) {
is KtFunctionLikeSymbol -> substitute(symbol, substitutor)
is KtVariableLikeSymbol -> substitute(symbol, substitutor)
@@ -51,42 +26,15 @@
public abstract fun <S : KtVariableLikeSymbol> substitute(symbol: S, substitutor: KtSubstitutor): KtVariableLikeSignature<S>
- public open fun <S : KtCallableSymbol> asSignature(symbol: S): KtCallableSignature<S> =
- substitute(symbol, KtSubstitutor.Empty(token))
+ public abstract fun <S : KtCallableSymbol> asSignature(symbol: S): KtCallableSignature<S>
- public open fun <S : KtFunctionLikeSymbol> asSignature(symbol: S): KtFunctionLikeSignature<S> =
- substitute(symbol, KtSubstitutor.Empty(token))
+ public abstract fun <S : KtFunctionLikeSymbol> asSignature(symbol: S): KtFunctionLikeSignature<S>
- public open fun <S : KtVariableLikeSymbol> asSignature(symbol: S): KtVariableLikeSignature<S> =
- substitute(symbol, KtSubstitutor.Empty(token))
+ public abstract fun <S : KtVariableLikeSymbol> asSignature(symbol: S): KtVariableLikeSignature<S>
}
public interface KtSignatureSubstitutorMixIn : KtAnalysisSessionMixIn {
/**
- * Applies a [substitutor] to the given signature and return a new signature with substituted types.
- *
- * @see KtSubstitutor.substitute
- */
- public fun <S : KtCallableSymbol> KtCallableSignature<S>.substitute(substitutor: KtSubstitutor): KtCallableSignature<S> =
- withValidityAssertion { analysisSession.signatureSubstitutor.substitute(this, substitutor) }
-
- /**
- * Applies a [substitutor] to the given signature and return a new signature with substituted types.
- *
- * @see KtSubstitutor.substitute
- */
- public fun <S : KtFunctionLikeSymbol> KtFunctionLikeSignature<S>.substitute(substitutor: KtSubstitutor): KtFunctionLikeSignature<S> =
- withValidityAssertion { analysisSession.signatureSubstitutor.substitute(this, substitutor) }
-
- /**
- * Applies a [substitutor] to the given signature and return a new signature with substituted types.
- *
- * @see KtSubstitutor.substitute
- */
- public fun <S : KtVariableLikeSymbol> KtVariableLikeSignature<S>.substitute(substitutor: KtSubstitutor): KtVariableLikeSignature<S> =
- withValidityAssertion { analysisSession.signatureSubstitutor.substitute(this, substitutor) }
-
- /**
* Applies a [substitutor] to the given symbol and return a signature with substituted types.
*
* @see KtSubstitutor.substitute
diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtCallableSignature.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtCallableSignature.kt
index 52f3b34..a5c8b98 100644
--- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtCallableSignature.kt
+++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/signatures/KtCallableSignature.kt
@@ -8,6 +8,7 @@
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
+import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.CallableId
@@ -43,6 +44,13 @@
*/
public open val callableIdIfNonLocal: CallableId? get() = withValidityAssertion { symbol.callableIdIfNonLocal }
+ /**
+ * Applies a [substitutor] to the given signature and return a new signature with substituted types.
+ *
+ * @see KtSubstitutor.substitute
+ */
+ public abstract fun substitute(substitutor: KtSubstitutor): KtCallableSignature<S>
+
abstract override fun equals(other: Any?): Boolean
abstract override fun hashCode(): Int
}
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 0576652..83b334a 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,57 +5,19 @@
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.types.KtType
+import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
/**
* A signature of a function-like symbol. This includes functions, getters, setters, lambdas, etc.
*/
-public class KtFunctionLikeSignature<out S : KtFunctionLikeSymbol>(
- private val _symbol: S,
- private val _returnType: KtType,
- private val _receiverType: KtType?,
- private val _valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>>,
-) : KtCallableSignature<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 }
-
+public abstract class KtFunctionLikeSignature<out S : KtFunctionLikeSymbol> : KtCallableSignature<S>() {
/**
* The use-site-substituted value parameters.
*/
- public val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>>
- get() = withValidityAssertion { _valueParameters }
+ public abstract val valueParameters: List<KtVariableLikeSignature<KtValueParameterSymbol>>
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (javaClass != other?.javaClass) return false
-
- other as KtFunctionLikeSignature<*>
-
- if (_symbol != other._symbol) return false
- if (_returnType != other._returnType) return false
- if (_receiverType != other._receiverType) return false
- if (_valueParameters != other._valueParameters) return false
-
- return true
- }
-
- override fun hashCode(): Int {
- var result = _symbol.hashCode()
- result = 31 * result + _returnType.hashCode()
- result = 31 * result + (_receiverType?.hashCode() ?: 0)
- result = 31 * result + _valueParameters.hashCode()
- return result
- }
+ abstract override fun substitute(substitutor: KtSubstitutor): KtFunctionLikeSignature<S>
}
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 1403f7f..64a5868 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,9 +8,9 @@
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.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.name.Name
@@ -21,20 +21,7 @@
/**
* A signature of a variable-like symbol. This includes properties, enum entries local variables, etc.
*/
-public class KtVariableLikeSignature<out S : KtVariableLikeSymbol>(
- private val _symbol: S,
- private val _returnType: KtType,
- private val _receiverType: KtType?,
-) : KtCallableSignature<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 }
-
+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].
*
@@ -66,11 +53,13 @@
//
// fun foo(x: (item: Int) -> Unit) { x(1) }
// fun bar(x: Function1<@ParameterName("item") Int, Unit>) { x(1) }
- val nameCanBeDeclaredInAnnotation = _symbol.psi == null
+ val nameCanBeDeclaredInAnnotation = symbol.psi == null
- runIf(nameCanBeDeclaredInAnnotation) { getValueFromParameterNameAnnotation() } ?: _symbol.name
+ runIf(nameCanBeDeclaredInAnnotation) { getValueFromParameterNameAnnotation() } ?: symbol.name
}
+ abstract override fun substitute(substitutor: KtSubstitutor): KtVariableLikeSignature<S>
+
private fun getValueFromParameterNameAnnotation(): Name? {
val resultingAnnotation = findParameterNameAnnotation() ?: return null
val parameterNameArgument = resultingAnnotation.arguments
@@ -91,24 +80,4 @@
implicitAnnotations.singleOrNull()
}
}
-
- override fun equals(other: Any?): Boolean {
- if (this === other) return true
- if (javaClass != other?.javaClass) return false
-
- other as KtVariableLikeSignature<*>
-
- if (_symbol != other._symbol) return false
- if (_returnType != other._returnType) return false
- if (_receiverType != other._receiverType) return false
-
- return true
- }
-
- override fun hashCode(): Int {
- var result = _symbol.hashCode()
- result = 31 * result + _returnType.hashCode()
- result = 31 * result + (_receiverType?.hashCode() ?: 0)
- return result
- }
}