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| { ^ 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| { ^ 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|) (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 = val calleeReference =
qualifiedAccessExpression.calleeReference as? FirNamedReferenceWithCandidate ?: return qualifiedAccessExpression.compose() qualifiedAccessExpression.calleeReference as? FirNamedReferenceWithCandidate ?: return qualifiedAccessExpression.compose()
val subCandidate = calleeReference.candidate
val candidateFir = calleeReference.candidateSymbol.phasedFir val candidateFir = calleeReference.candidateSymbol.phasedFir
val typeArguments = computeTypeArguments(qualifiedAccessExpression, calleeReference.candidate) val typeArguments = computeTypeArguments(qualifiedAccessExpression, calleeReference.candidate)
val typeRef = (candidateFir as? FirTypedDeclaration)?.let { val typeRef = (candidateFir as? FirTypedDeclaration)?.let { typedDeclaration ->
typeCalculator.tryCalculateReturnType(it) typeCalculator.tryCalculateReturnType(typedDeclaration).let {
if (qualifiedAccessExpression.safe) {
val nullableType = it.coneTypeUnsafe<ConeKotlinType>().withNullability(
ConeNullability.NULLABLE, session.inferenceContext
)
it.withReplacedConeType(nullableType)
} else {
it
}
}
} ?: buildErrorTypeRef { } ?: buildErrorTypeRef {
source = calleeReference.source source = calleeReference.source
diagnostic = ConeSimpleDiagnostic("Callee reference to candidate without return type: ${candidateFir.render()}") 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( val resultType = typeRef.substituteTypeRef(subCandidate)
StoreCalleeReference, result.replaceTypeRef(resultType)
buildResolvedNamedReference { result.replaceTypeArguments(typeArguments)
source = calleeReference.source
name = calleeReference.name return result.compose()
resolvedSymbol = calleeReference.candidateSymbol
},
).apply {
replaceTypeArguments(typeArguments)
}.compose()
} }
private fun <D : FirExpression> D.replaceTypeRefWithSubstituted( private fun <D : FirExpression> D.replaceTypeRefWithSubstituted(
@@ -146,7 +162,7 @@ class FirCallCompletionResultsWriterTransformer(
name = calleeReference.name name = calleeReference.name
resolvedSymbol = calleeReference.candidateSymbol resolvedSymbol = calleeReference.candidateSymbol
}, },
).apply { ).transformExplicitReceiver(integerApproximator, null).apply {
replaceTypeArguments(typeArguments) replaceTypeArguments(typeArguments)
}.compose() }.compose()
} }