[Analysis API FIR] Initialize properties of KtCallableSignature lazily

This commit is contained in:
aleksandrina-streltsova
2023-04-13 14:01:57 +02:00
committed by teamcity
parent 2eab9fc00f
commit 2cc3b542fd
17 changed files with 496 additions and 245 deletions
@@ -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)
}
}
}
@@ -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)
}
}
@@ -33,7 +33,6 @@ import kotlin.reflect.full.memberProperties
@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 @@ internal fun KtAnalysisSession.stringRepresentation(any: Any): String = with(any
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 @@ internal fun KtAnalysisSession.stringRepresentation(any: Any): String = with(any
}
}
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 -> {