FIR resolve completion: transform receivers for variable accesses

This commit is contained in:
Mikhail Glukhikh
2020-04-22 16:19:42 +03:00
parent ab79e60b63
commit b0b198119d
2 changed files with 31 additions and 15 deletions
@@ -32,7 +32,7 @@ FILE: threeReceiversCorrect.kt
}
)
^ R|/with|<R|B|, R|kotlin/Unit|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Unit| {
this@R|special/anonymous|.R|/A.foo|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/c|)
(this@R|special/anonymous|, this@R|special/anonymous|).R|/A.foo|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/c|)
^ R|/with|<R|C|, R|kotlin/Unit|>(R|<local>/c|, <L> = with@fun R|C|.<anonymous>(): R|kotlin/Unit| {
(this@R|special/anonymous|, this@R|special/anonymous|).R|/A.foo|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(this@R|special/anonymous|)
}
@@ -56,27 +56,43 @@ class FirCallCompletionResultsWriterTransformer(
val calleeReference =
qualifiedAccessExpression.calleeReference as? FirNamedReferenceWithCandidate ?: return qualifiedAccessExpression.compose()
val subCandidate = calleeReference.candidate
val candidateFir = calleeReference.candidateSymbol.phasedFir
val typeArguments = computeTypeArguments(qualifiedAccessExpression, calleeReference.candidate)
val typeRef = (candidateFir as? FirTypedDeclaration)?.let {
typeCalculator.tryCalculateReturnType(it)
val typeRef = (candidateFir as? FirTypedDeclaration)?.let { typedDeclaration ->
typeCalculator.tryCalculateReturnType(typedDeclaration).let {
if (qualifiedAccessExpression.safe) {
val nullableType = it.coneTypeUnsafe<ConeKotlinType>().withNullability(
ConeNullability.NULLABLE, session.inferenceContext
)
it.withReplacedConeType(nullableType)
} else {
it
}
}
} ?: buildErrorTypeRef {
source = calleeReference.source
diagnostic = ConeSimpleDiagnostic("Callee reference to candidate without return type: ${candidateFir.render()}")
}
qualifiedAccessExpression.replaceTypeRefWithSubstituted(calleeReference, typeRef).replaceTypeArguments(typeArguments)
val result = qualifiedAccessExpression
.transformCalleeReference(
StoreCalleeReference,
buildResolvedNamedReference {
source = calleeReference.source
name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol
},
)
.transformDispatchReceiver(StoreReceiver, subCandidate.dispatchReceiverExpression())
.transformExtensionReceiver(StoreReceiver, subCandidate.extensionReceiverExpression())
.transformExplicitReceiver(integerApproximator, null)
return qualifiedAccessExpression.transformCalleeReference(
StoreCalleeReference,
buildResolvedNamedReference {
source = calleeReference.source
name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol
},
).apply {
replaceTypeArguments(typeArguments)
}.compose()
val resultType = typeRef.substituteTypeRef(subCandidate)
result.replaceTypeRef(resultType)
result.replaceTypeArguments(typeArguments)
return result.compose()
}
private fun <D : FirExpression> D.replaceTypeRefWithSubstituted(
@@ -146,7 +162,7 @@ class FirCallCompletionResultsWriterTransformer(
name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol
},
).apply {
).transformExplicitReceiver(integerApproximator, null).apply {
replaceTypeArguments(typeArguments)
}.compose()
}