[FIR] Transform all qualified access nodes with smartcasts
This commit is contained in:
+15
-16
@@ -203,7 +203,7 @@ open class FirBodyResolveTransformer(
|
|||||||
data: Any?
|
data: Any?
|
||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
|
|
||||||
val result = when (val callee = qualifiedAccessExpression.calleeReference) {
|
var result = when (val callee = qualifiedAccessExpression.calleeReference) {
|
||||||
is FirExplicitThisReference -> {
|
is FirExplicitThisReference -> {
|
||||||
val labelName = callee.labelName
|
val labelName = callee.labelName
|
||||||
val implicitReceiver = implicitReceiverStack[labelName]
|
val implicitReceiver = implicitReceiverStack[labelName]
|
||||||
@@ -241,33 +241,32 @@ open class FirBodyResolveTransformer(
|
|||||||
val transformedCallee = callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression, file)
|
val transformedCallee = callResolver.resolveVariableAccessAndSelectCandidate(qualifiedAccessExpression, file)
|
||||||
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
|
// NB: here we can get raw expression because of dropped qualifiers (see transform callee),
|
||||||
// so candidate existence must be checked before calling completion
|
// so candidate existence must be checked before calling completion
|
||||||
val result = if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
|
if (transformedCallee is FirQualifiedAccessExpression && transformedCallee.candidate() != null) {
|
||||||
callCompleter.completeCall(transformedCallee, data as? FirTypeRef)
|
callCompleter.completeCall(transformedCallee, data as? FirTypeRef)
|
||||||
} else {
|
} else {
|
||||||
transformedCallee
|
transformedCallee
|
||||||
}
|
}
|
||||||
if (result is FirQualifiedAccessExpression) {
|
|
||||||
dataFlowAnalyzer.getTypeUsingSmartcastInfo(result)?.let { typesFromSmartCast ->
|
|
||||||
val allTypes = typesFromSmartCast.toMutableList().also {
|
|
||||||
it += result.resultType.coneTypeUnsafe<ConeKotlinType>()
|
|
||||||
}
|
|
||||||
val intersectedType = ConeTypeIntersector.intersectTypes(inferenceComponents.ctx as ConeInferenceContext, allTypes)
|
|
||||||
// TODO: add check that intersectedType is not equal to original type
|
|
||||||
FirExpressionWithSmartcastImpl(result, typesFromSmartCast).also {
|
|
||||||
it.resultType = FirResolvedTypeRefImpl(result.psi, intersectedType, result.resultType.annotations)
|
|
||||||
}
|
|
||||||
} ?: result
|
|
||||||
} else {
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result is FirQualifiedAccessExpression) {
|
if (result is FirQualifiedAccessExpression) {
|
||||||
|
result = transformQualifiedAccessUsingSmartcastInfo(result)
|
||||||
dataFlowAnalyzer.exitQualifiedAccessExpression(result)
|
dataFlowAnalyzer.exitQualifiedAccessExpression(result)
|
||||||
}
|
}
|
||||||
return result.compose()
|
return result.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun transformQualifiedAccessUsingSmartcastInfo(qualifiedAccessExpression: FirQualifiedAccessExpression): FirQualifiedAccessExpression {
|
||||||
|
val typesFromSmartCast = dataFlowAnalyzer.getTypeUsingSmartcastInfo(qualifiedAccessExpression) ?: return qualifiedAccessExpression
|
||||||
|
val allTypes = typesFromSmartCast.toMutableList().also {
|
||||||
|
it += qualifiedAccessExpression.resultType.coneTypeUnsafe<ConeKotlinType>()
|
||||||
|
}
|
||||||
|
val intersectedType = ConeTypeIntersector.intersectTypes(inferenceComponents.ctx as ConeInferenceContext, allTypes)
|
||||||
|
// TODO: add check that intersectedType is not equal to original type
|
||||||
|
return FirExpressionWithSmartcastImpl(qualifiedAccessExpression, typesFromSmartCast).also {
|
||||||
|
it.resultType = FirResolvedTypeRefImpl(qualifiedAccessExpression.resultType.psi, intersectedType, qualifiedAccessExpression.resultType.annotations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun transformVariableAssignment(
|
override fun transformVariableAssignment(
|
||||||
variableAssignment: FirVariableAssignment,
|
variableAssignment: FirVariableAssignment,
|
||||||
data: Any?
|
data: Any?
|
||||||
|
|||||||
Reference in New Issue
Block a user