[FIR IDE] Add getDispatchReceiverType function and use
This function is under a heavy deprecation and should not be used, since it will most probably be removed in the future
This commit is contained in:
committed by
TeamCityServer
parent
3091269035
commit
4e1e1570df
+18
-1
@@ -5,21 +5,26 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.descriptors.components
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.assertIsValidAndAccessible
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtBuiltinTypes
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtTypeProvider
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.base.KtFe10Symbol
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.KtFe10DescSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.classId
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.getSymbolDescriptor
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.isInterfaceLike
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.KtFe10PsiSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.getResolutionScope
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.utils.PublicApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossibleMemberSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.nameOrAnonymous
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
@@ -39,7 +44,6 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||
import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
import org.jetbrains.kotlin.util.containingNonLocalDeclaration
|
||||
|
||||
internal class KtFe10TypeProvider(
|
||||
@@ -115,6 +119,19 @@ internal class KtFe10TypeProvider(
|
||||
return TypeUtils.getAllSupertypes(type.type).map { it.toKtType(analysisContext) }
|
||||
}
|
||||
|
||||
override fun getDispatchReceiverType(symbol: KtPossibleMemberSymbol): KtType? {
|
||||
assertIsValidAndAccessible()
|
||||
require(symbol is KtFe10Symbol)
|
||||
|
||||
val descriptor = when (symbol) {
|
||||
is KtFe10DescSymbol<*> -> symbol.descriptor as? CallableDescriptor
|
||||
is KtFe10PsiSymbol<*, *> -> symbol.descriptor as? CallableDescriptor
|
||||
else -> error("No callable descriptor on $symbol")
|
||||
}
|
||||
|
||||
return descriptor?.dispatchReceiverParameter?.type?.toKtType(analysisContext)
|
||||
}
|
||||
|
||||
private fun areTypesCompatible(a: KotlinType, b: KotlinType): Boolean {
|
||||
if (a.isNothing() || b.isNothing() || TypeUtils.equalTypes(a, b) || (a.isNullable() && b.isNullable())) {
|
||||
return true
|
||||
|
||||
+15
@@ -9,10 +9,12 @@ import org.jetbrains.kotlin.analysis.api.components.KtBuiltinTypes
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtTypeProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
|
||||
import org.jetbrains.kotlin.analysis.api.fir.types.PublicTypeApproximator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.toConeNullability
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossibleMemberSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||
@@ -25,6 +27,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker.isCompatible
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||
@@ -183,5 +186,17 @@ internal class KtFirTypeProvider(
|
||||
.drop(1)
|
||||
.mapTo(mutableListOf()) { it.asKtType() }
|
||||
}
|
||||
|
||||
override fun getDispatchReceiverType(symbol: KtPossibleMemberSymbol): KtType? {
|
||||
require(symbol is KtFirSymbol<*>)
|
||||
|
||||
return symbol.firRef.withFir { declaration ->
|
||||
check(declaration is FirCallableDeclaration) {
|
||||
"Fir declaration should be FirCallableDeclaration; instead it was ${declaration::class}"
|
||||
}
|
||||
|
||||
declaration.dispatchReceiverType?.asKtType()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-6
@@ -37,7 +37,7 @@ abstract class AbstractResolveCallTest(configurator: FrontendApiTestConfigurator
|
||||
|
||||
val actual = executeOnPooledThreadInReadAction {
|
||||
analyseForTest(expression) {
|
||||
resolveCall(expression)?.stringRepresentation()
|
||||
resolveCall(expression)?.let { stringRepresentation(it) }
|
||||
}
|
||||
} ?: "null"
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
@@ -62,8 +62,8 @@ abstract class AbstractResolveCallTest(configurator: FrontendApiTestConfigurator
|
||||
|
||||
}
|
||||
|
||||
private fun KtCall.stringRepresentation(): String {
|
||||
fun KtType.render() = substitutor.substituteOrSelf(this).asStringForDebugging().replace('/', '.')
|
||||
private fun KtAnalysisSession.stringRepresentation(call: KtCall): String {
|
||||
fun KtType.render() = call.substitutor.substituteOrSelf(this).asStringForDebugging().replace('/', '.')
|
||||
fun Any.stringValue(): String = when (this) {
|
||||
is KtFunctionLikeSymbol -> buildString {
|
||||
append(
|
||||
@@ -81,7 +81,9 @@ private fun KtCall.stringRepresentation(): String {
|
||||
append("<extension receiver>: ${receiver.type.render()}")
|
||||
if (valueParameters.isNotEmpty()) append(", ")
|
||||
}
|
||||
(this@stringValue as? KtPossibleMemberSymbol)?.dispatchType?.let { dispatchReceiverType ->
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
(this@stringValue as? KtPossibleMemberSymbol)?.getDispatchReceiverType()?.let { dispatchReceiverType ->
|
||||
append("<dispatch receiver>: ${dispatchReceiverType.render()}")
|
||||
if (valueParameters.isNotEmpty()) append(", ")
|
||||
}
|
||||
@@ -108,7 +110,7 @@ private fun KtCall.stringRepresentation(): String {
|
||||
else -> error("unexpected parameter type ${this::class}")
|
||||
}
|
||||
|
||||
val callInfoClass = this::class
|
||||
val callInfoClass = call::class
|
||||
return buildString {
|
||||
append(callInfoClass.simpleName!!)
|
||||
append(":\n")
|
||||
@@ -118,7 +120,7 @@ private fun KtCall.stringRepresentation(): String {
|
||||
.filter { it.name != "token" }
|
||||
.joinTo(this, separator = "\n") { parameter ->
|
||||
val name = parameter.name!!.removePrefix("_")
|
||||
val value = propertyByName[name]!!.javaGetter!!(this@stringRepresentation)?.stringValue()
|
||||
val value = propertyByName[name]!!.javaGetter!!(call)?.stringValue()
|
||||
"$name = $value"
|
||||
}
|
||||
}
|
||||
|
||||
+17
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.components
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossibleMemberSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtFlexibleType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||
@@ -37,6 +38,7 @@ public abstract class KtTypeProvider : KtAnalysisSessionComponent() {
|
||||
|
||||
public abstract fun getAllSuperTypes(type: KtType, shouldApproximate: Boolean): List<KtType>
|
||||
|
||||
public abstract fun getDispatchReceiverType(symbol: KtPossibleMemberSymbol): KtType?
|
||||
}
|
||||
|
||||
public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
|
||||
@@ -118,6 +120,21 @@ public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
|
||||
*/
|
||||
public fun KtType.getAllSuperTypes(shouldApproximate: Boolean = false): List<KtType> =
|
||||
analysisSession.typeProvider.getAllSuperTypes(this, shouldApproximate)
|
||||
|
||||
/**
|
||||
* This function is provided for a few use-cases where it's hard to go without it.
|
||||
*
|
||||
* **Please avoid using it**; it will probably be removed in the future.
|
||||
*
|
||||
* The function is instantly deprecated, so it's not shown in the completion.
|
||||
*
|
||||
* @receiver A target callable symbol.
|
||||
* @return A dispatch receiver type for this symbol if it has any.
|
||||
*/
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
@Deprecated("Avoid using this function")
|
||||
public fun KtPossibleMemberSymbol.getDispatchReceiverType(): KtType? =
|
||||
analysisSession.typeProvider.getDispatchReceiverType(this)
|
||||
}
|
||||
|
||||
@Suppress("PropertyName")
|
||||
|
||||
Reference in New Issue
Block a user