[API Usage] Add type refinement for callable references
This commit is contained in:
committed by
Dmitry Savvinov
parent
53334c038f
commit
696aea004d
+31
-2
@@ -45,8 +45,10 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
|||||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
|
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
|
||||||
|
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||||
import org.jetbrains.kotlin.types.expressions.FunctionWithBigAritySupport.LanguageVersionDependent
|
import org.jetbrains.kotlin.types.expressions.FunctionWithBigAritySupport.LanguageVersionDependent
|
||||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
|
||||||
|
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
@@ -74,6 +76,28 @@ sealed class DoubleColonLHS(val type: KotlinType) {
|
|||||||
class Type(type: KotlinType, val possiblyBareType: PossiblyBareType) : DoubleColonLHS(type)
|
class Type(type: KotlinType, val possiblyBareType: PossiblyBareType) : DoubleColonLHS(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TypeRefinement
|
||||||
|
private fun KotlinTypeRefiner.refineBareType(type: PossiblyBareType): PossiblyBareType {
|
||||||
|
if (type.isBare) return type
|
||||||
|
val newType = type.actualType.let { refineType(it) }
|
||||||
|
return PossiblyBareType.type(newType)
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseExperimental(TypeRefinement::class)
|
||||||
|
private fun <T : DoubleColonLHS> KotlinTypeRefiner.refineLHS(lhs: T): T = when (lhs) {
|
||||||
|
is DoubleColonLHS.Expression -> {
|
||||||
|
val newType = lhs.typeInfo.type?.let { refineType(it) }
|
||||||
|
DoubleColonLHS.Expression(
|
||||||
|
lhs.typeInfo.replaceType(newType),
|
||||||
|
lhs.isObjectQualifier
|
||||||
|
) as T
|
||||||
|
}
|
||||||
|
is DoubleColonLHS.Type -> {
|
||||||
|
DoubleColonLHS.Type(refineType(lhs.type), refineBareType(lhs.possiblyBareType)) as T
|
||||||
|
}
|
||||||
|
else -> throw IllegalStateException()
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if this expression has the form "A<B>" which means it's a type on the LHS of a double colon expression
|
// Returns true if this expression has the form "A<B>" which means it's a type on the LHS of a double colon expression
|
||||||
internal val KtCallExpression.isWithoutValueArguments: Boolean
|
internal val KtCallExpression.isWithoutValueArguments: Boolean
|
||||||
get() = valueArgumentList == null && lambdaArguments.isEmpty()
|
get() = valueArgumentList == null && lambdaArguments.isEmpty()
|
||||||
@@ -88,7 +112,8 @@ class DoubleColonExpressionResolver(
|
|||||||
val additionalCheckers: Iterable<ClassLiteralChecker>,
|
val additionalCheckers: Iterable<ClassLiteralChecker>,
|
||||||
val dataFlowValueFactory: DataFlowValueFactory,
|
val dataFlowValueFactory: DataFlowValueFactory,
|
||||||
val bigAritySupport: FunctionWithBigAritySupport,
|
val bigAritySupport: FunctionWithBigAritySupport,
|
||||||
val genericArrayClassLiteralSupport: GenericArrayClassLiteralSupport
|
val genericArrayClassLiteralSupport: GenericArrayClassLiteralSupport,
|
||||||
|
val kotlinTypeRefiner: KotlinTypeRefiner
|
||||||
) {
|
) {
|
||||||
private lateinit var expressionTypingServices: ExpressionTypingServices
|
private lateinit var expressionTypingServices: ExpressionTypingServices
|
||||||
|
|
||||||
@@ -346,7 +371,11 @@ class DoubleColonExpressionResolver(
|
|||||||
if (isReservedExpressionSyntax) return doubleColonLHS
|
if (isReservedExpressionSyntax) return doubleColonLHS
|
||||||
|
|
||||||
val resultForType = tryResolveLHS(doubleColonExpression, c, this::shouldTryResolveLHSAsType) { expression, context ->
|
val resultForType = tryResolveLHS(doubleColonExpression, c, this::shouldTryResolveLHSAsType) { expression, context ->
|
||||||
resolveTypeOnLHS(expression, doubleColonExpression, context)
|
resolveTypeOnLHS(expression, doubleColonExpression, context)?.let {
|
||||||
|
// If lhs is not expression then ExpressionTypingVisitor don't refine it's type and we should do this manually
|
||||||
|
@UseExperimental(TypeRefinement::class)
|
||||||
|
DoubleColonLHS.Type(kotlinTypeRefiner.refineType(it.type), kotlinTypeRefiner.refineBareType(it.possiblyBareType))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (resultForType != null) {
|
if (resultForType != null) {
|
||||||
val lhs = resultForType.lhs
|
val lhs = resultForType.lhs
|
||||||
|
|||||||
Reference in New Issue
Block a user