[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
|
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.KtBuiltinTypes
|
||||||
import org.jetbrains.kotlin.analysis.api.components.KtTypeProvider
|
import org.jetbrains.kotlin.analysis.api.components.KtTypeProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
|
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
|
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.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.classId
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.getSymbolDescriptor
|
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.isInterfaceLike
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
|
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.symbols.psiBased.base.getResolutionScope
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
|
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.PublicApproximatorConfiguration
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
|
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
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.symbols.nameOrAnonymous
|
||||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
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.NewCapturedType
|
||||||
import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor
|
import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
|
||||||
import org.jetbrains.kotlin.util.containingNonLocalDeclaration
|
import org.jetbrains.kotlin.util.containingNonLocalDeclaration
|
||||||
|
|
||||||
internal class KtFe10TypeProvider(
|
internal class KtFe10TypeProvider(
|
||||||
@@ -115,6 +119,19 @@ internal class KtFe10TypeProvider(
|
|||||||
return TypeUtils.getAllSupertypes(type.type).map { it.toKtType(analysisContext) }
|
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 {
|
private fun areTypesCompatible(a: KotlinType, b: KotlinType): Boolean {
|
||||||
if (a.isNothing() || b.isNothing() || TypeUtils.equalTypes(a, b) || (a.isNullable() && b.isNullable())) {
|
if (a.isNothing() || b.isNothing() || TypeUtils.equalTypes(a, b) || (a.isNullable() && b.isNullable())) {
|
||||||
return true
|
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.components.KtTypeProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
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.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.KtFirType
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.types.PublicTypeApproximator
|
import org.jetbrains.kotlin.analysis.api.fir.types.PublicTypeApproximator
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.utils.toConeNullability
|
import org.jetbrains.kotlin.analysis.api.fir.utils.toConeNullability
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
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.tokens.ValidityToken
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
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.ConeTypeCompatibilityChecker.isCompatible
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
|
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols
|
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.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||||
@@ -183,5 +186,17 @@ internal class KtFirTypeProvider(
|
|||||||
.drop(1)
|
.drop(1)
|
||||||
.mapTo(mutableListOf()) { it.asKtType() }
|
.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 {
|
val actual = executeOnPooledThreadInReadAction {
|
||||||
analyseForTest(expression) {
|
analyseForTest(expression) {
|
||||||
resolveCall(expression)?.stringRepresentation()
|
resolveCall(expression)?.let { stringRepresentation(it) }
|
||||||
}
|
}
|
||||||
} ?: "null"
|
} ?: "null"
|
||||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||||
@@ -62,8 +62,8 @@ abstract class AbstractResolveCallTest(configurator: FrontendApiTestConfigurator
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtCall.stringRepresentation(): String {
|
private fun KtAnalysisSession.stringRepresentation(call: KtCall): String {
|
||||||
fun KtType.render() = substitutor.substituteOrSelf(this).asStringForDebugging().replace('/', '.')
|
fun KtType.render() = call.substitutor.substituteOrSelf(this).asStringForDebugging().replace('/', '.')
|
||||||
fun Any.stringValue(): String = when (this) {
|
fun Any.stringValue(): String = when (this) {
|
||||||
is KtFunctionLikeSymbol -> buildString {
|
is KtFunctionLikeSymbol -> buildString {
|
||||||
append(
|
append(
|
||||||
@@ -81,7 +81,9 @@ private fun KtCall.stringRepresentation(): String {
|
|||||||
append("<extension receiver>: ${receiver.type.render()}")
|
append("<extension receiver>: ${receiver.type.render()}")
|
||||||
if (valueParameters.isNotEmpty()) append(", ")
|
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()}")
|
append("<dispatch receiver>: ${dispatchReceiverType.render()}")
|
||||||
if (valueParameters.isNotEmpty()) append(", ")
|
if (valueParameters.isNotEmpty()) append(", ")
|
||||||
}
|
}
|
||||||
@@ -108,7 +110,7 @@ private fun KtCall.stringRepresentation(): String {
|
|||||||
else -> error("unexpected parameter type ${this::class}")
|
else -> error("unexpected parameter type ${this::class}")
|
||||||
}
|
}
|
||||||
|
|
||||||
val callInfoClass = this::class
|
val callInfoClass = call::class
|
||||||
return buildString {
|
return buildString {
|
||||||
append(callInfoClass.simpleName!!)
|
append(callInfoClass.simpleName!!)
|
||||||
append(":\n")
|
append(":\n")
|
||||||
@@ -118,7 +120,7 @@ private fun KtCall.stringRepresentation(): String {
|
|||||||
.filter { it.name != "token" }
|
.filter { it.name != "token" }
|
||||||
.joinTo(this, separator = "\n") { parameter ->
|
.joinTo(this, separator = "\n") { parameter ->
|
||||||
val name = parameter.name!!.removePrefix("_")
|
val name = parameter.name!!.removePrefix("_")
|
||||||
val value = propertyByName[name]!!.javaGetter!!(this@stringRepresentation)?.stringValue()
|
val value = propertyByName[name]!!.javaGetter!!(call)?.stringValue()
|
||||||
"$name = $value"
|
"$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.ValidityTokenOwner
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
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.KtFlexibleType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
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 getAllSuperTypes(type: KtType, shouldApproximate: Boolean): List<KtType>
|
||||||
|
|
||||||
|
public abstract fun getDispatchReceiverType(symbol: KtPossibleMemberSymbol): KtType?
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
|
public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
|
||||||
@@ -118,6 +120,21 @@ public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn {
|
|||||||
*/
|
*/
|
||||||
public fun KtType.getAllSuperTypes(shouldApproximate: Boolean = false): List<KtType> =
|
public fun KtType.getAllSuperTypes(shouldApproximate: Boolean = false): List<KtType> =
|
||||||
analysisSession.typeProvider.getAllSuperTypes(this, shouldApproximate)
|
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")
|
@Suppress("PropertyName")
|
||||||
|
|||||||
Reference in New Issue
Block a user