[FIR] Replace usages of FirExpression.typeRef with coneTypeOrNull

#KT-59855 Fixed
This commit is contained in:
Kirill Rakhman
2023-08-04 10:43:25 +02:00
committed by Space Team
parent f60d81097c
commit 8d7c5b375e
76 changed files with 538 additions and 565 deletions
@@ -72,7 +72,7 @@ internal class KtFirExpressionTypeProvider(
// For unresolved `super`, we manually create an intersection type so that IDE features like completion can work correctly.
val containingClass = (fir.dispatchReceiver as? FirThisReceiverExpression)?.calleeReference?.boundSymbol as? FirClassSymbol<*>
if (fir.calleeReference is FirSuperReference && fir.typeRef is FirErrorTypeRef && containingClass != null) {
if (fir.calleeReference is FirSuperReference && fir.coneTypeOrNull is ConeErrorType && containingClass != null) {
val superTypes = containingClass.resolvedSuperTypes
when (superTypes.size) {
0 -> analysisSession.builtinTypes.ANY
@@ -214,9 +214,7 @@ internal class KtFirExpressionTypeProvider(
private fun getExpectedTypeByTypeCast(expression: PsiElement): KtType? {
val typeCastExpression =
expression.unwrapQualified<KtBinaryExpressionWithTypeRHS> { castExpr, expr -> castExpr.left == expr } ?: return null
with(analysisSession) {
return typeCastExpression.right?.getKtType()
}
return getKtExpressionType(typeCastExpression)
}
private fun getExpectedTypeOfFunctionParameter(expression: PsiElement): KtType? {
@@ -178,13 +178,13 @@ internal object FirCompileTimeConstantEvaluator {
val opr1 = evaluate(functionCall.explicitReceiver, mode) ?: return null
opr1.evaluate(function)?.let {
return it.adjustType(functionCall.type)
return it.adjustType(functionCall.coneTypeOrNull)
}
val argument = functionCall.arguments.firstOrNull() ?: return null
val opr2 = evaluate(argument, mode) ?: return null
opr1.evaluate(function, opr2)?.let {
return it.adjustType(functionCall.type)
return it.adjustType(functionCall.coneTypeOrNull)
}
return null
}
@@ -207,7 +207,7 @@ internal object FirCompileTimeConstantEvaluator {
}
// Lastly, we should preserve the resolved type of the original function call.
return expression.apply {
replaceType(expectedType)
replaceConeTypeOrNull(expectedType)
}
}
@@ -422,7 +422,7 @@ internal object FirReferenceResolveHelper {
// accessing the `super` property on `this`, hence this weird looking if condition. In addition, the current class type is available
// from the dispatch receiver `this`.
if (expression is KtLabelReferenceExpression && fir is FirPropertyAccessExpression && fir.calleeReference is FirSuperReference) {
return listOfNotNull(fir.dispatchReceiver.type?.toTargetSymbol(session, symbolBuilder))
return listOfNotNull(fir.dispatchReceiver.coneTypeOrNull?.toTargetSymbol(session, symbolBuilder))
}
val receiverOrImplicitInvoke = if (fir is FirImplicitInvokeCall) {
fir.explicitReceiver?.unwrapSmartcastExpression()
@@ -733,7 +733,7 @@ internal object FirReferenceResolveHelper {
session: FirSession,
symbolBuilder: KtSymbolByFirBuilder
): Collection<KtSymbol> {
val type = fir.type ?: return emptyList()
val type = fir.coneTypeOrNull ?: return emptyList()
return listOfNotNull(type.toTargetSymbol(session, symbolBuilder))
}
@@ -218,7 +218,7 @@ internal open class FirElementsRecorder : FirVisitor<Unit, MutableMap<KtElement,
convertedValue as T,
setType = false
).also {
it.replaceTypeRef(original.typeRef)
it.replaceConeTypeOrNull(original.coneTypeOrNull)
}
}
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinClassTypeBean
import org.jetbrains.kotlin.psi.stubs.impl.KotlinPropertyStubImpl
import org.jetbrains.kotlin.types.ConstantValueKind
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
class StubBasedAnnotationDeserializer(
private val session: FirSession,
@@ -109,23 +108,20 @@ class StubBasedAnnotationDeserializer(
source = KtRealPsiSourceElement(sourceElement)
val lookupTag = (value.value as KClassValue.Value.NormalClass).classId.toLookupTag()
val referencedType = lookupTag.constructType(ConeTypeProjection.EMPTY_ARRAY, isNullable = false)
val resolvedTypeRef = buildResolvedTypeRef {
type = StandardClassIds.KClass.constructClassLikeType(arrayOf(referencedType), false)
}
val resolvedType = StandardClassIds.KClass.constructClassLikeType(arrayOf(referencedType), false)
argumentList = buildUnaryArgumentList(
buildClassReferenceExpression {
classTypeRef = buildResolvedTypeRef { type = referencedType }
typeRef = resolvedTypeRef
coneTypeOrNull = resolvedType
}
)
coneTypeOrNull = resolvedType
}
is ArrayValue -> {
buildArrayLiteral {
source = KtRealPsiSourceElement(sourceElement)
typeRef = buildResolvedTypeRef {
// Not quite precise, yet doesn't require annotation resolution
type = (inferArrayValueType(value.value) ?: session.builtinTypes.anyType.type).createArrayType()
}
// Not quite precise, yet doesn't require annotation resolution
coneTypeOrNull = (inferArrayValueType(value.value) ?: session.builtinTypes.anyType.type).createArrayType()
argumentList = buildArgumentList {
value.value.mapTo(arguments) { resolveValue(sourceElement, it) }
@@ -208,7 +204,7 @@ class StubBasedAnnotationDeserializer(
kind,
value,
setType = true
).apply { this.replaceTypeRef(typeRef) }
).apply { this.replaceConeTypeOrNull(typeRef.type) }
}
private fun PsiElement.toEnumEntryReferenceExpression(classId: ClassId, entryName: Name): FirExpression {
@@ -228,7 +224,7 @@ class StubBasedAnnotationDeserializer(
name = entryName
}
if (enumEntrySymbol != null) {
typeRef = enumEntrySymbol.returnTypeRef
coneTypeOrNull = enumEntrySymbol.returnTypeRef.coneTypeOrNull
}
}
}
@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolve
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractsDslNames
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isUsedInControlFlowGraphBuilderForClass
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -399,7 +398,7 @@ private val FirFunction.isCertainlyResolved: Boolean
}
val body = this.body ?: return false // Not completely sure
return body !is FirLazyBlock && body.typeRef is FirResolvedTypeRef
return body !is FirLazyBlock && body.coneTypeOrNull != null
}
private val FirVariable.initializerIfUnresolved: FirExpression?
@@ -472,4 +471,4 @@ private fun requireSameSize(old: List<FirStatement>, new: List<FirStatement>) {
private class LLFirCodeFragmentContext(
override val towerDataContext: FirTowerDataContext,
override val variables: Map<FirBasedSymbol<*>, Set<ConeKotlinType>>
) : FirCodeFragmentContext
) : FirCodeFragmentContext
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvable
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList
import org.jetbrains.kotlin.fir.references.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -49,6 +50,26 @@ internal inline fun checkTypeRefIsResolved(
}
}
internal inline fun checkExpressionTypeIsResolved(
type: ConeKotlinType?,
typeName: String,
owner: FirElementWithResolveState,
extraAttachment: ExceptionAttachmentBuilder.() -> Unit = {},
) {
checkWithAttachment(
condition = type != null,
message = {
buildString {
append("Expected resolved expression type")
append(" for $typeName of ${owner::class.simpleName}(${(owner as? FirDeclaration)?.origin})")
}
}
) {
withFirEntry("firDeclaration", owner)
extraAttachment()
}
}
internal fun <T> checkAnnotationTypeIsResolved(annotationContainer: T) where T : FirAnnotationContainer, T : FirElementWithResolveState {
annotationContainer.annotations.forEach { annotation ->
checkTypeRefIsResolved(annotation.annotationTypeRef, "annotation type", owner = annotationContainer) {
@@ -59,7 +80,7 @@ internal fun <T> checkAnnotationTypeIsResolved(annotationContainer: T) where T :
internal fun checkBodyIsResolved(function: FirFunction) {
val block = function.body ?: return
checkTypeRefIsResolved(block.typeRef, "block type", function) {
checkExpressionTypeIsResolved(block.coneTypeOrNull, "block type", function) {
withFirEntry("block", block)
}
}
@@ -67,7 +88,7 @@ internal fun checkBodyIsResolved(function: FirFunction) {
internal fun checkStatementsAreResolved(script: FirScript) {
for (statement in script.statements) {
if (statement.isScriptStatement && statement is FirExpression) {
checkTypeRefIsResolved(statement.typeRef, "script statement", script) {
checkExpressionTypeIsResolved(statement.coneTypeOrNull, "script statement", script) {
withFirEntry("expression", statement)
}
}
@@ -114,14 +135,14 @@ internal fun checkReferenceIsResolved(
internal fun checkInitializerIsResolved(variable: FirVariable) {
val initializer = variable.initializer ?: return
checkTypeRefIsResolved(initializer.typeRef, "initializer type", variable) {
checkExpressionTypeIsResolved(initializer.coneTypeOrNull, "initializer type", variable) {
withFirEntry("initializer", initializer)
}
}
internal fun checkDefaultValueIsResolved(parameter: FirValueParameter) {
val defaultValue = parameter.defaultValue ?: return
checkTypeRefIsResolved(defaultValue.typeRef, "default value type", parameter) {
checkExpressionTypeIsResolved(defaultValue.coneTypeOrNull, "default value type", parameter) {
withFirEntry("defaultValue", defaultValue)
}
}
@@ -194,7 +215,7 @@ internal fun <T> checkAnnotationArgumentsMappingIsResolved(
}
for (argument in annotation.argumentMapping.mapping.values) {
checkTypeRefIsResolved(argument.typeRef, "annotation argument", annotationContainer) {
checkExpressionTypeIsResolved(argument.coneTypeOrNull, "annotation argument", annotationContainer) {
withFirEntry("firAnnotation", annotation)
withFirEntry("firArgument", argument)
}
@@ -9,7 +9,7 @@ FIR FILE:
FILE: [ResolvedTo(IMPORTS)] javaClassLiteral.kt
public final [ResolvedTo(BODY_RESOLVE)] fun main([ResolvedTo(BODY_RESOLVE)] args: R|kotlin/Array<kotlin/String>|): R|kotlin/Unit| {
[ResolvedTo(BODY_RESOLVE)] lval anyClass: R|kotlin/Any| = R|kotlin/Any.Any|()
R|/funOne|(<ERROR TYPE REF: Qualified expression with unexpected selector>ERROR_EXPR(Incorrect selector expression)R|<local>/anyClass|)
R|/funOne|(ERROR_EXPR(Incorrect selector expression)R|<local>/anyClass|)
}
public final [ResolvedTo(CONTRACTS)] fun funOne([ResolvedTo(CONTRACTS)] x: R|kotlin/Any|): R|kotlin/Unit| {
}
@@ -14,7 +14,7 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedPartOfQualifiedCallUnresolved.kt
public final [ResolvedTo(BODY_RESOLVE)] fun handleLeftBracketInFragment(): R|kotlin/Unit| {
{
[ResolvedTo(BODY_RESOLVE)] lval <receiver>: <ERROR TYPE REF: Unresolved name: peek> = <Unresolved name: peek>#()
[ResolvedTo(BODY_RESOLVE)] lval <receiver>: R|ERROR CLASS: Unresolved name: peek| = <Unresolved name: peek>#()
[ResolvedTo(BODY_RESOLVE)] lval <unary>: <ERROR TYPE REF: Unresolved name: braceBalance> = R|<local>/<receiver>|.<Unresolved name: braceBalance>#
R|<local>/<receiver>|.<Unresolved name: braceBalance># = R|<local>/<unary>|.<Unresolved name: inc>#()
R|<local>/<unary>|
@@ -18,7 +18,7 @@ FILE: [ResolvedTo(IMPORTS)] qualifiedPartOfQualifiedCallUnresolvedScript.kts
public final [ResolvedTo(BODY_RESOLVE)] fun handleLeftBracketInFragment(): R|kotlin/Unit| {
{
[ResolvedTo(BODY_RESOLVE)] lval <receiver>: <ERROR TYPE REF: Unresolved name: peek> = <Unresolved name: peek>#()
[ResolvedTo(BODY_RESOLVE)] lval <receiver>: R|ERROR CLASS: Unresolved name: peek| = <Unresolved name: peek>#()
[ResolvedTo(BODY_RESOLVE)] lval <unary>: <ERROR TYPE REF: Unresolved name: braceBalance> = R|<local>/<receiver>|.<Unresolved name: braceBalance>#
R|<local>/<receiver>|.<Unresolved name: braceBalance># = R|<local>/<unary>|.<Unresolved name: inc>#()
R|<local>/<unary>|