[FIR] Rename FirExpression.coneType to resolvedType

This commit is contained in:
Kirill Rakhman
2023-08-21 17:50:23 +02:00
committed by Space Team
parent ab6d87a1a2
commit 7fde5af7f8
91 changed files with 364 additions and 342 deletions
@@ -421,7 +421,7 @@ internal class KtFirCallResolver(
val extensionReceiverValue: KtReceiverValue? val extensionReceiverValue: KtReceiverValue?
if (explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER) { if (explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER) {
dispatchReceiverValue = dispatchReceiverValue =
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.coneType.asKtType(), false, token) KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.resolvedType.asKtType(), false, token)
if (firstArgIsExtensionReceiver) { if (firstArgIsExtensionReceiver) {
extensionReceiverValue = (fir as FirFunctionCall).arguments.firstOrNull()?.toKtReceiverValue() extensionReceiverValue = (fir as FirFunctionCall).arguments.firstOrNull()?.toKtReceiverValue()
} else { } else {
@@ -430,7 +430,7 @@ internal class KtFirCallResolver(
} else { } else {
dispatchReceiverValue = dispatchReceiver.toKtReceiverValue() dispatchReceiverValue = dispatchReceiver.toKtReceiverValue()
extensionReceiverValue = extensionReceiverValue =
KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.coneType.asKtType(), false, token) KtExplicitReceiverValue(explicitReceiverPsi, extensionReceiver.resolvedType.asKtType(), false, token)
} }
return KtPartiallyAppliedSymbol( return KtPartiallyAppliedSymbol(
with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) }, with(analysisSession) { unsubstitutedKtSignature.substitute(substitutor) },
@@ -777,12 +777,12 @@ internal class KtFirCallResolver(
(calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol ?: return null (calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol ?: return null
val substitutor = createConeSubstitutorFromTypeArguments() ?: return null val substitutor = createConeSubstitutorFromTypeArguments() ?: return null
val dispatchReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == dispatchReceiver) { val dispatchReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == dispatchReceiver) {
explicitReceiverPsiSupplement.toExplicitReceiverValue(dispatchReceiver.coneType.asKtType()) explicitReceiverPsiSupplement.toExplicitReceiverValue(dispatchReceiver.resolvedType.asKtType())
} else { } else {
dispatchReceiver.toKtReceiverValue() dispatchReceiver.toKtReceiverValue()
} }
val extensionReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == extensionReceiver) { val extensionReceiverValue = if (explicitReceiverPsiSupplement != null && explicitReceiver == extensionReceiver) {
explicitReceiverPsiSupplement.toExplicitReceiverValue(extensionReceiver.coneType.asKtType()) explicitReceiverPsiSupplement.toExplicitReceiverValue(extensionReceiver.resolvedType.asKtType())
} else { } else {
extensionReceiver.toKtReceiverValue() extensionReceiver.toKtReceiverValue()
} }
@@ -811,12 +811,12 @@ internal class KtFirCallResolver(
?: return null ?: return null
else -> return null else -> return null
} }
KtImplicitReceiverValue(implicitPartiallyAppliedSymbol, coneType.asKtType()) KtImplicitReceiverValue(implicitPartiallyAppliedSymbol, resolvedType.asKtType())
} }
else -> { else -> {
val psi = psi val psi = psi
if (psi !is KtExpression) return null if (psi !is KtExpression) return null
psi.toExplicitReceiverValue(coneType.asKtType()) psi.toExplicitReceiverValue(resolvedType.asKtType())
} }
} }
} }
@@ -1169,7 +1169,7 @@ internal class KtFirCallResolver(
val equalsSymbolInAny = equalsSymbolInAny val equalsSymbolInAny = equalsSymbolInAny
val leftOperand = arguments.firstOrNull() ?: return null val leftOperand = arguments.firstOrNull() ?: return null
val session = analysisSession.useSiteSession val session = analysisSession.useSiteSession
val leftOperandType = leftOperand.coneType val leftOperandType = leftOperand.resolvedType
val classSymbol = leftOperandType.fullyExpandedType(session).toSymbol(session) as? FirClassSymbol<*> val classSymbol = leftOperandType.fullyExpandedType(session).toSymbol(session) as? FirClassSymbol<*>
val equalsSymbol = classSymbol?.getEqualsSymbol(equalsSymbolInAny) ?: equalsSymbolInAny val equalsSymbol = classSymbol?.getEqualsSymbol(equalsSymbolInAny) ?: equalsSymbolInAny
@@ -31,8 +31,8 @@ import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
import org.jetbrains.kotlin.psi.psiUtil.getOutermostParenthesizerOrThis import org.jetbrains.kotlin.psi.psiUtil.getOutermostParenthesizerOrThis
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
import org.jetbrains.kotlin.utils.exceptions.rethrowExceptionWithDetails import org.jetbrains.kotlin.utils.exceptions.rethrowExceptionWithDetails
import org.jetbrains.kotlin.utils.exceptions.withPsiEntry import org.jetbrains.kotlin.utils.exceptions.withPsiEntry
@@ -67,7 +67,7 @@ internal class KtFirExpressionTypeProvider(
} }
private fun getKtExpressionType(expression: KtExpression, fir: FirElement): KtType? = when (fir) { private fun getKtExpressionType(expression: KtExpression, fir: FirElement): KtType? = when (fir) {
is FirFunctionCall -> getReturnTypeForArrayStyleAssignmentTarget(expression, fir) ?: fir.coneType.asKtType() is FirFunctionCall -> getReturnTypeForArrayStyleAssignmentTarget(expression, fir) ?: fir.resolvedType.asKtType()
is FirPropertyAccessExpression -> { is FirPropertyAccessExpression -> {
// For unresolved `super`, we manually create an intersection type so that IDE features like completion can work correctly. // 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<*> val containingClass = (fir.dispatchReceiver as? FirThisReceiverExpression)?.calleeReference?.boundSymbol as? FirClassSymbol<*>
@@ -80,19 +80,19 @@ internal class KtFirExpressionTypeProvider(
else -> ConeIntersectionType(superTypes).asKtType() else -> ConeIntersectionType(superTypes).asKtType()
} }
} else { } else {
fir.coneType.asKtType() fir.resolvedType.asKtType()
} }
} }
is FirVariableAssignment -> { is FirVariableAssignment -> {
if (fir.lValue.source?.psi == expression) { if (fir.lValue.source?.psi == expression) {
fir.lValue.coneType.asKtType() fir.lValue.resolvedType.asKtType()
} else if (expression is KtUnaryExpression && expression.operationToken in KtTokens.INCREMENT_AND_DECREMENT) { } else if (expression is KtUnaryExpression && expression.operationToken in KtTokens.INCREMENT_AND_DECREMENT) {
fir.rValue.coneType.asKtType() fir.rValue.resolvedType.asKtType()
} else { } else {
analysisSession.builtinTypes.UNIT analysisSession.builtinTypes.UNIT
} }
} }
is FirExpression -> fir.coneType.asKtType() is FirExpression -> fir.resolvedType.asKtType()
is FirNamedReference -> fir.getCorrespondingTypeIfPossible()?.asKtType() is FirNamedReference -> fir.getCorrespondingTypeIfPossible()?.asKtType()
is FirStatement -> with(analysisSession) { builtinTypes.UNIT } is FirStatement -> with(analysisSession) { builtinTypes.UNIT }
is FirTypeRef, is FirImport, is FirPackageDirective, is FirLabel, is FirTypeParameterRef -> null is FirTypeRef, is FirImport, is FirPackageDirective, is FirLabel, is FirTypeParameterRef -> null
@@ -123,7 +123,7 @@ internal class KtFirExpressionTypeProvider(
* of the whole expression instead, and that is not what he wants. * of the whole expression instead, and that is not what he wants.
*/ */
private fun FirNamedReference.getCorrespondingTypeIfPossible(): ConeKotlinType? = private fun FirNamedReference.getCorrespondingTypeIfPossible(): ConeKotlinType? =
findOuterPropertyAccessExpression()?.coneType findOuterPropertyAccessExpression()?.resolvedType
/** /**
* Finds an outer expression for [this] named reference in cases when it is a part of a property access. * Finds an outer expression for [this] named reference in cases when it is a part of a property access.
@@ -425,7 +425,7 @@ internal class KtFirExpressionTypeProvider(
private fun getDefiniteNullability(expression: KtExpression): DefiniteNullability { private fun getDefiniteNullability(expression: KtExpression): DefiniteNullability {
fun FirExpression.isNotNullable() = with(analysisSession.useSiteSession.typeContext) { fun FirExpression.isNotNullable() = with(analysisSession.useSiteSession.typeContext) {
!coneType.isNullableType() !resolvedType.isNullableType()
} }
when (val fir = expression.getOrBuildFir(analysisSession.firResolveSession)) { when (val fir = expression.getOrBuildFir(analysisSession.firResolveSession)) {
@@ -36,23 +36,13 @@ import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
import org.jetbrains.kotlin.psi.KtDoubleColonExpression
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.model.CaptureStatus import org.jetbrains.kotlin.types.model.CaptureStatus
import org.jetbrains.kotlin.util.bfs import org.jetbrains.kotlin.util.bfs
@@ -172,9 +162,9 @@ internal class KtFirTypeProvider(
override fun getReceiverTypeForDoubleColonExpression(expression: KtDoubleColonExpression): KtType? { override fun getReceiverTypeForDoubleColonExpression(expression: KtDoubleColonExpression): KtType? {
return when (val fir = expression.getOrBuildFir(firResolveSession)) { return when (val fir = expression.getOrBuildFir(firResolveSession)) {
is FirGetClassCall -> is FirGetClassCall ->
fir.coneType.getReceiverOfReflectionType()?.asKtType() fir.resolvedType.getReceiverOfReflectionType()?.asKtType()
is FirCallableReferenceAccess -> is FirCallableReferenceAccess ->
fir.coneType.getReceiverOfReflectionType()?.asKtType() fir.resolvedType.getReceiverOfReflectionType()?.asKtType()
else -> throwUnexpectedFirElementError(fir, expression) else -> throwUnexpectedFirElementError(fir, expression)
} }
} }
@@ -179,7 +179,7 @@ internal object FirAnnotationValueConverter {
val qualifierParts = mutableListOf<String?>() val qualifierParts = mutableListOf<String?>()
fun process(expression: FirExpression) { fun process(expression: FirExpression) {
val errorType = expression.coneType as? ConeErrorType val errorType = expression.resolvedType as? ConeErrorType
val unresolvedName = when (val diagnostic = errorType?.diagnostic) { val unresolvedName = when (val diagnostic = errorType?.diagnostic) {
is ConeUnresolvedTypeQualifierError -> diagnostic.qualifier is ConeUnresolvedTypeQualifierError -> diagnostic.qualifier
is ConeUnresolvedNameError -> diagnostic.qualifier is ConeUnresolvedNameError -> diagnostic.qualifier
@@ -261,7 +261,7 @@ internal object FirReferenceResolveHelper {
symbolBuilder: KtSymbolByFirBuilder symbolBuilder: KtSymbolByFirBuilder
): Collection<KtSymbol> { ): Collection<KtSymbol> {
val lhs = expression.arguments.firstOrNull() ?: return emptyList() val lhs = expression.arguments.firstOrNull() ?: return emptyList()
val scope = lhs.coneType.scope( val scope = lhs.resolvedType.scope(
session, session,
analysisSession.getScopeSessionFor(analysisSession.useSiteSession), analysisSession.getScopeSessionFor(analysisSession.useSiteSession),
FakeOverrideTypeCalculator.DoNothing, FakeOverrideTypeCalculator.DoNothing,
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.delegateFieldsMap import org.jetbrains.kotlin.fir.declarations.delegateFieldsMap
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.ConeDynamicType import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
object FirJsDynamicDeclarationChecker : FirClassChecker() { object FirJsDynamicDeclarationChecker : FirClassChecker() {
override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -27,7 +27,7 @@ object FirJsDynamicDeclarationChecker : FirClassChecker() {
// and it's a shape it couldn't have been accessed directly // and it's a shape it couldn't have been accessed directly
val initializer = delegate.fir.initializer ?: continue val initializer = delegate.fir.initializer ?: continue
if (initializer.coneType is ConeDynamicType) { if (initializer.resolvedType is ConeDynamicType) {
reporter.reportOn(initializer.source, FirJsErrors.DELEGATION_BY_DYNAMIC, context) reporter.reportOn(initializer.source, FirJsErrors.DELEGATION_BY_DYNAMIC, context)
} }
} }
@@ -10,12 +10,12 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.closestNonLocalWith import org.jetbrains.kotlin.fir.analysis.checkers.closestNonLocalWith
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
import org.jetbrains.kotlin.fir.analysis.checkers.isTopLevel import org.jetbrains.kotlin.fir.analysis.checkers.isTopLevel
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.name.JsStandardClassIds import org.jetbrains.kotlin.name.JsStandardClassIds
object FirJsExternalFileChecker : FirBasicDeclarationChecker() { object FirJsExternalFileChecker : FirBasicDeclarationChecker() {
@@ -34,7 +34,7 @@ object FirJsExternalFileChecker : FirBasicDeclarationChecker() {
reporter.reportOn( reporter.reportOn(
declaration.source, declaration.source,
FirJsErrors.NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE, FirJsErrors.NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE,
targetAnnotations.coneType, targetAnnotations.resolvedType,
context context
) )
} }
@@ -10,9 +10,9 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirSimpleFunctionChecker import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirSimpleFunctionChecker
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
import org.jetbrains.kotlin.fir.analysis.checkers.isTopLevel import org.jetbrains.kotlin.fir.analysis.checkers.isTopLevel
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeObject
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
@@ -36,7 +36,7 @@ internal abstract class FirJsAbstractNativeAnnotationChecker(private val require
reporter.reportOn( reporter.reportOn(
declaration.source, declaration.source,
FirJsErrors.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN, FirJsErrors.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN,
annotation.coneType, annotation.resolvedType,
context context
) )
} }
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.analysis.js.checkers.sanitizeName import org.jetbrains.kotlin.fir.analysis.js.checkers.sanitizeName
@@ -21,7 +20,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.resolved import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.types.ConeDynamicType import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
private val nameToOperator = mapOf( private val nameToOperator = mapOf(
@@ -90,7 +89,7 @@ object FirJsDynamicCallChecker : FirQualifiedAccessExpressionChecker() {
private fun checkSpreadOperator(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) { private fun checkSpreadOperator(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
forAllSpreadArgumentsOf(expression) { forAllSpreadArgumentsOf(expression) {
if (it.coneType is ConeDynamicType) { if (it.resolvedType is ConeDynamicType) {
reporter.reportOn(it.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "spread operator", context) reporter.reportOn(it.source, FirJsErrors.WRONG_OPERATION_WITH_DYNAMIC, "spread operator", context)
} }
} }
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeInterface import org.jetbrains.kotlin.fir.analysis.js.checkers.isNativeInterface
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirJsNativeRttiChecker : FirBasicExpressionChecker() { object FirJsNativeRttiChecker : FirBasicExpressionChecker() {
@@ -26,7 +27,7 @@ object FirJsNativeRttiChecker : FirBasicExpressionChecker() {
} }
private fun checkGetClassCall(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) { private fun checkGetClassCall(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) {
val declarationToCheck = expression.argument.coneType.toRegularClassSymbol(context.session) ?: return val declarationToCheck = expression.argument.resolvedType.toRegularClassSymbol(context.session) ?: return
if (expression.arguments.firstOrNull() !is FirResolvedQualifier) { if (expression.arguments.firstOrNull() !is FirResolvedQualifier) {
return return
@@ -49,7 +50,7 @@ object FirJsNativeRttiChecker : FirBasicExpressionChecker() {
FirOperation.AS, FirOperation.SAFE_AS -> reporter.reportOn( FirOperation.AS, FirOperation.SAFE_AS -> reporter.reportOn(
expression.source, expression.source,
FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE, FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE,
expression.argument.coneType, expression.argument.resolvedType,
targetTypeRef.coneType, targetTypeRef.coneType,
context, context,
) )
@@ -13,12 +13,15 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclaratio
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.declarations.utils.isOverridable
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.resolve.getContainingClass import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
@@ -28,7 +31,7 @@ object FirJvmNameChecker : FirBasicDeclarationChecker() {
val jvmName = declaration.findJvmNameAnnotation() ?: return val jvmName = declaration.findJvmNameAnnotation() ?: return
val name = jvmName.findArgumentByName(StandardNames.NAME) ?: return val name = jvmName.findArgumentByName(StandardNames.NAME) ?: return
if (name.coneType != context.session.builtinTypes.stringType.type) { if (name.resolvedType != context.session.builtinTypes.stringType.type) {
return return
} }
@@ -70,7 +70,7 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
// Anything is acceptable for raw types // Anything is acceptable for raw types
if (expectedType is ConeRawType) continue if (expectedType is ConeRawType) continue
val argType = arg.coneType val argType = arg.resolvedType
val lowerBound = expectedType.lowerBound val lowerBound = expectedType.lowerBound
val upperBound = expectedType.upperBound val upperBound = expectedType.upperBound
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.fir.types.typeContext
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_CLASS_ID import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_CLASS_ID
@@ -38,7 +38,7 @@ object FirJvmProtectedInSuperClassCompanionCallChecker : FirBasicExpressionCheck
} ?: return } ?: return
if (dispatchReceiver is FirNoReceiverExpression) return if (dispatchReceiver is FirNoReceiverExpression) return
val dispatchClassSymbol = dispatchReceiver.coneType.toRegularClassSymbol(context.session) ?: return val dispatchClassSymbol = dispatchReceiver.resolvedType.toRegularClassSymbol(context.session) ?: return
val calleeReference = expression.calleeReference val calleeReference = expression.calleeReference
val resolvedSymbol = calleeReference?.toResolvedCallableSymbol() ?: return val resolvedSymbol = calleeReference?.toResolvedCallableSymbol() ?: return
@@ -12,13 +12,13 @@ import org.jetbrains.kotlin.fir.analysis.native.checkers.forwardDeclarationKindO
import org.jetbrains.kotlin.fir.expressions.FirGetClassCall import org.jetbrains.kotlin.fir.expressions.FirGetClassCall
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirNativeForwardDeclarationGetClassCallChecker : FirGetClassCallChecker() { object FirNativeForwardDeclarationGetClassCallChecker : FirGetClassCallChecker() {
override fun check(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) {
val declarationToCheck = expression.argument.coneType.toRegularClassSymbol(context.session) ?: return val declarationToCheck = expression.argument.resolvedType.toRegularClassSymbol(context.session) ?: return
if (expression.arguments.firstOrNull() !is FirResolvedQualifier) { if (expression.arguments.firstOrNull() !is FirResolvedQualifier) {
return return
@@ -28,7 +28,7 @@ object FirNativeForwardDeclarationGetClassCallChecker : FirGetClassCallChecker()
reporter.reportOn( reporter.reportOn(
expression.source, expression.source,
FirNativeErrors.FORWARD_DECLARATION_AS_CLASS_LITERAL, FirNativeErrors.FORWARD_DECLARATION_AS_CLASS_LITERAL,
expression.argument.coneType, expression.argument.resolvedType,
context, context,
) )
} }
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.expressions.argument
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirNativeForwardDeclarationTypeOperatorChecker : FirTypeOperatorCallChecker() { object FirNativeForwardDeclarationTypeOperatorChecker : FirTypeOperatorCallChecker() {
@@ -27,7 +28,7 @@ object FirNativeForwardDeclarationTypeOperatorChecker : FirTypeOperatorCallCheck
when (expression.operation) { when (expression.operation) {
FirOperation.AS, FirOperation.SAFE_AS -> { FirOperation.AS, FirOperation.SAFE_AS -> {
val sourceClass = expression.argument.coneType.toRegularClassSymbol(context.session) val sourceClass = expression.argument.resolvedType.toRegularClassSymbol(context.session)
// It can make sense to avoid warning if sourceClass is subclass of class with such property, // It can make sense to avoid warning if sourceClass is subclass of class with such property,
// but for the sake of simplicity, we don't do it now. // but for the sake of simplicity, we don't do it now.
if (sourceClass != null && sourceClass.classKind == fwdKind.classKind && sourceClass.name == declarationToCheck.name) { if (sourceClass != null && sourceClass.classKind == fwdKind.classKind && sourceClass.name == declarationToCheck.name) {
@@ -44,8 +45,8 @@ object FirNativeForwardDeclarationTypeOperatorChecker : FirTypeOperatorCallCheck
reporter.reportOn( reporter.reportOn(
expression.source, expression.source,
FirNativeErrors.UNCHECKED_CAST_TO_FORWARD_DECLARATION, FirNativeErrors.UNCHECKED_CAST_TO_FORWARD_DECLARATION,
expression.argument.coneType, expression.argument.resolvedType,
expression.argument.coneType, expression.argument.resolvedType,
context, context,
) )
} }
@@ -12,12 +12,16 @@ import org.jetbrains.kotlin.fir.analysis.cfa.util.previousCfgNodes
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.contracts.description.* import org.jetbrains.kotlin.fir.contracts.description.ConeConditionalEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.description.ConeReturnsEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.effects import org.jetbrains.kotlin.fir.contracts.effects
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
import org.jetbrains.kotlin.fir.resolve.dfa.* import org.jetbrains.kotlin.fir.resolve.dfa.*
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.BlockExitNode import org.jetbrains.kotlin.fir.resolve.dfa.cfg.BlockExitNode
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode import org.jetbrains.kotlin.fir.resolve.dfa.cfg.CFGNode
@@ -78,7 +82,7 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
val isReturn = node is JumpNode && node.fir is FirReturnExpression val isReturn = node is JumpNode && node.fir is FirReturnExpression
val resultExpression = if (isReturn) (node.fir as FirReturnExpression).result else node.fir val resultExpression = if (isReturn) (node.fir as FirReturnExpression).result else node.fir
val expressionType = (resultExpression as? FirExpression)?.coneType val expressionType = (resultExpression as? FirExpression)?.resolvedType
if (expressionType == builtinTypes.nothingType.type) return false if (expressionType == builtinTypes.nothingType.type) return false
if (isReturn && resultExpression is FirWhenExpression) { if (isReturn && resultExpression is FirWhenExpression) {
@@ -85,7 +85,7 @@ internal fun checkConstantArguments(
} }
} }
expression is FirGetClassCall -> { expression is FirGetClassCall -> {
var coneType = (expression as? FirCall)?.argument?.coneType var coneType = (expression as? FirCall)?.argument?.resolvedType
if (coneType is ConeErrorType) if (coneType is ConeErrorType)
return ConstantArgumentKind.NOT_CONST return ConstantArgumentKind.NOT_CONST
@@ -109,7 +109,7 @@ internal fun checkConstantArguments(
} }
expressionSymbol is FirConstructorSymbol -> { expressionSymbol is FirConstructorSymbol -> {
if (expression is FirCallableReferenceAccess) return null if (expression is FirCallableReferenceAccess) return null
if (expression.coneType.isUnsignedType) { if (expression.resolvedType.isUnsignedType) {
(expression as FirFunctionCall).arguments.forEach { argumentExpression -> (expression as FirFunctionCall).arguments.forEach { argumentExpression ->
checkConstantArguments(argumentExpression, session)?.let { return it } checkConstantArguments(argumentExpression, session)?.let { return it }
} }
@@ -122,7 +122,7 @@ internal fun checkConstantArguments(
if (calleeReference is FirErrorNamedReference) { if (calleeReference is FirErrorNamedReference) {
return null return null
} }
if (expression.coneType.classId == StandardClassIds.KClass) { if (expression.resolvedType.classId == StandardClassIds.KClass) {
return ConstantArgumentKind.NOT_KCLASS_LITERAL return ConstantArgumentKind.NOT_KCLASS_LITERAL
} }
@@ -140,7 +140,7 @@ internal fun checkConstantArguments(
for (exp in expression.arguments.plus(expression.dispatchReceiver).plus(expression.extensionReceiver)) { for (exp in expression.arguments.plus(expression.dispatchReceiver).plus(expression.extensionReceiver)) {
if (exp is FirNoReceiverExpression) continue if (exp is FirNoReceiverExpression) continue
val expClassId = exp.coneType.lowerBoundIfFlexible().classId val expClassId = exp.resolvedType.lowerBoundIfFlexible().classId
// TODO, KT-59823: add annotation for allowed constant types // TODO, KT-59823: add annotation for allowed constant types
if (expClassId !in StandardClassIds.constantAllowedTypes) { if (expClassId !in StandardClassIds.constantAllowedTypes) {
return ConstantArgumentKind.NOT_CONST return ConstantArgumentKind.NOT_CONST
@@ -152,8 +152,11 @@ internal fun checkConstantArguments(
return null return null
} }
expression is FirQualifiedAccessExpression -> { expression is FirQualifiedAccessExpression -> {
val expressionType = expression.coneType val expressionType = expression.resolvedType
if (expressionType.isReflectFunctionType(session) || expressionType.isKProperty(session) || expressionType.isKMutableProperty(session)) { if (expressionType.isReflectFunctionType(session) || expressionType.isKProperty(session) || expressionType.isKMutableProperty(
session
)
) {
return checkConstantArguments(expression.dispatchReceiver, session) return checkConstantArguments(expression.dispatchReceiver, session)
} }
@@ -163,7 +166,8 @@ internal fun checkConstantArguments(
val property = propertySymbol.fir val property = propertySymbol.fir
when { when {
property.unwrapFakeOverrides().symbol.canBeEvaluated() || property.isCompileTimeBuiltinProperty() -> { property.unwrapFakeOverrides().symbol.canBeEvaluated() || property.isCompileTimeBuiltinProperty() -> {
val receiver = listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != FirNoReceiverExpression } val receiver =
listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != FirNoReceiverExpression }
return checkConstantArguments(receiver, session) return checkConstantArguments(receiver, session)
} }
propertySymbol.isLocal || propertySymbol.callableId.className?.isRoot == false -> return ConstantArgumentKind.NOT_CONST propertySymbol.isLocal || propertySymbol.callableId.className?.isRoot == false -> return ConstantArgumentKind.NOT_CONST
@@ -195,7 +199,7 @@ private fun FirExpression.isForbiddenComplexConstant(session: FirSession): Boole
private val FirExpression.isComplexBooleanConstant private val FirExpression.isComplexBooleanConstant
get(): Boolean = when { get(): Boolean = when {
!coneType.isBoolean -> false !resolvedType.isBoolean -> false
this is FirConstExpression<*> -> false this is FirConstExpression<*> -> false
usesVariableAsConstant -> false usesVariableAsConstant -> false
else -> true else -> true
@@ -38,7 +38,10 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET
import org.jetbrains.kotlin.resolve.AnnotationTargetList import org.jetbrains.kotlin.resolve.AnnotationTargetList
@@ -452,7 +455,7 @@ fun checkTypeMismatch(
isInitializer: Boolean isInitializer: Boolean
) { ) {
var lValueType = lValueOriginalType var lValueType = lValueOriginalType
var rValueType = rValue.coneType var rValueType = rValue.resolvedType
if (source.kind is KtFakeSourceElementKind.DesugaredIncrementOrDecrement) { if (source.kind is KtFakeSourceElementKind.DesugaredIncrementOrDecrement) {
if (!lValueType.isNullable && rValueType.isNullable) { if (!lValueType.isNullable && rValueType.isNullable) {
val tempType = rValueType val tempType = rValueType
@@ -512,7 +515,7 @@ fun checkTypeMismatch(
} }
internal fun checkCondition(condition: FirExpression, context: CheckerContext, reporter: DiagnosticReporter) { internal fun checkCondition(condition: FirExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val coneType = condition.coneType.lowerBoundIfFlexible() val coneType = condition.resolvedType.lowerBoundIfFlexible()
if (coneType !is ConeErrorType && !coneType.isSubtypeOf(context.session.typeContext, context.session.builtinTypes.booleanType.type)) { if (coneType !is ConeErrorType && !coneType.isSubtypeOf(context.session.typeContext, context.session.builtinTypes.booleanType.type)) {
reporter.reportOn( reporter.reportOn(
condition.source, condition.source,
@@ -6,10 +6,10 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirBlock
@@ -41,7 +41,7 @@ object FirAmbiguousAnonymousTypeChecker : FirBasicDeclarationChecker() {
* 3. `val x get() = ...` * 3. `val x get() = ...`
*/ */
val type = when (declaration) { val type = when (declaration) {
is FirProperty -> declaration.initializer?.coneType ?: declaration.getter?.body?.singleExpressionType is FirProperty -> declaration.initializer?.resolvedType ?: declaration.getter?.body?.singleExpressionType
is FirFunction -> declaration.body?.singleExpressionType is FirFunction -> declaration.body?.singleExpressionType
else -> error("Should not be there") else -> error("Should not be there")
} ?: return } ?: return
@@ -76,5 +76,5 @@ object FirAmbiguousAnonymousTypeChecker : FirBasicDeclarationChecker() {
} }
private val FirBlock.singleExpressionType private val FirBlock.singleExpressionType
get() = ((this as? FirSingleExpressionBlock)?.statement as? FirReturnExpression)?.result?.coneType get() = ((this as? FirSingleExpressionBlock)?.statement as? FirReturnExpression)?.result?.resolvedType
} }
@@ -5,10 +5,10 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.delegateFieldsMap import org.jetbrains.kotlin.fir.declarations.delegateFieldsMap
import org.jetbrains.kotlin.fir.expressions.FirCall import org.jetbrains.kotlin.fir.expressions.FirCall
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isSubtypeOf import org.jetbrains.kotlin.fir.types.isSubtypeOf
import org.jetbrains.kotlin.fir.types.resolvedType
object FirDelegateFieldTypeMismatchChecker : FirRegularClassChecker() { object FirDelegateFieldTypeMismatchChecker : FirRegularClassChecker() {
@SymbolInternals @SymbolInternals
@@ -29,13 +30,13 @@ object FirDelegateFieldTypeMismatchChecker : FirRegularClassChecker() {
if ( if (
!isReportedByErrorNodeDiagnosticCollector && !isReportedByErrorNodeDiagnosticCollector &&
!initializer.coneType.isSubtypeOf(supertype.coneType, context.session, true) !initializer.resolvedType.isSubtypeOf(supertype.coneType, context.session, true)
) { ) {
reporter.reportOn( reporter.reportOn(
initializer.source, initializer.source,
FirErrors.TYPE_MISMATCH, FirErrors.TYPE_MISMATCH,
field.returnTypeRef.coneType, field.returnTypeRef.coneType,
initializer.coneType, initializer.resolvedType,
false, false,
context, context,
) )
@@ -24,7 +24,7 @@ object FirDelegateUsesExtensionPropertyTypeParameterChecker : FirPropertyChecker
val delegate = declaration.delegate as? FirFunctionCall ?: return val delegate = declaration.delegate as? FirFunctionCall ?: return
val parameters = declaration.typeParameters.mapTo(hashSetOf()) { it.symbol } val parameters = declaration.typeParameters.mapTo(hashSetOf()) { it.symbol }
val usedTypeParameterSymbol = delegate.coneType.findUsedTypeParameterSymbol(parameters, delegate, context, reporter) val usedTypeParameterSymbol = delegate.resolvedType.findUsedTypeParameterSymbol(parameters, delegate, context, reporter)
?: return ?: return
reporter.reportOn(declaration.source, FirErrors.DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER, usedTypeParameterSymbol, context) reporter.reportOn(declaration.source, FirErrors.DELEGATE_USES_EXTENSION_PROPERTY_TYPE_PARAMETER, usedTypeParameterSymbol, context)
@@ -37,7 +37,7 @@ object FirDelegateUsesExtensionPropertyTypeParameterChecker : FirPropertyChecker
reporter: DiagnosticReporter, reporter: DiagnosticReporter,
): FirTypeParameterSymbol? { ): FirTypeParameterSymbol? {
val expandedDelegateClassLikeType = val expandedDelegateClassLikeType =
delegate.coneType.lowerBoundIfFlexible().fullyExpandedType(context.session) delegate.resolvedType.lowerBoundIfFlexible().fullyExpandedType(context.session)
.unwrapDefinitelyNotNull() as? ConeClassLikeType ?: return null .unwrapDefinitelyNotNull() as? ConeClassLikeType ?: return null
val delegateClassSymbol = expandedDelegateClassLikeType.lookupTag.toSymbol(context.session) as? FirRegularClassSymbol ?: return null val delegateClassSymbol = expandedDelegateClassLikeType.lookupTag.toSymbol(context.session) as? FirRegularClassSymbol ?: return null
val delegateClassScope by lazy { delegateClassSymbol.unsubstitutedScope(context) } val delegateClassScope by lazy { delegateClassSymbol.unsubstitutedScope(context) }
@@ -6,19 +6,17 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
import org.jetbrains.kotlin.fir.references.isError import org.jetbrains.kotlin.fir.references.isError
import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -30,7 +28,7 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
object FirDelegatedPropertyChecker : FirPropertyChecker() { object FirDelegatedPropertyChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
val delegate = declaration.delegate ?: return val delegate = declaration.delegate ?: return
val delegateType = delegate.coneType val delegateType = delegate.resolvedType
val source = delegate.source; val source = delegate.source;
if (delegateType is ConeErrorType) { if (delegateType is ConeErrorType) {
@@ -66,7 +64,7 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
val diagnostic = if (reference.isError()) reference.diagnostic else return false val diagnostic = if (reference.isError()) reference.diagnostic else return false
if (reference.source?.kind != KtFakeSourceElementKind.DelegatedPropertyAccessor) return false if (reference.source?.kind != KtFakeSourceElementKind.DelegatedPropertyAccessor) return false
val expectedFunctionSignature = val expectedFunctionSignature =
(if (isGet) "getValue" else "setValue") + "(${functionCall.arguments.joinToString(", ") { it.coneType.renderReadable() }})" (if (isGet) "getValue" else "setValue") + "(${functionCall.arguments.joinToString(", ") { it.resolvedType.renderReadable() }})"
val delegateDescription = if (isGet) "delegate" else "delegate for var (read-write property)" val delegateDescription = if (isGet) "delegate" else "delegate for var (read-write property)"
fun reportInapplicableDiagnostics(candidates: Collection<FirBasedSymbol<*>>) { fun reportInapplicableDiagnostics(candidates: Collection<FirBasedSymbol<*>>) {
@@ -124,7 +122,7 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
} }
private fun checkReturnType(functionCall: FirFunctionCall) { private fun checkReturnType(functionCall: FirFunctionCall) {
val returnType = functionCall.coneType val returnType = functionCall.resolvedType
val propertyType = declaration.returnTypeRef.coneType val propertyType = declaration.returnTypeRef.coneType
if (!AbstractTypeChecker.isSubtypeOf(context.session.typeContext, returnType, propertyType)) { if (!AbstractTypeChecker.isSubtypeOf(context.session.typeContext, returnType, propertyType)) {
reporter.reportOn( reporter.reportOn(
@@ -68,7 +68,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
val originalDestructuringDeclarationType = val originalDestructuringDeclarationType =
when (originalDestructuringDeclarationOrInitializer) { when (originalDestructuringDeclarationOrInitializer) {
is FirVariable -> originalDestructuringDeclarationOrInitializer.returnTypeRef.coneType is FirVariable -> originalDestructuringDeclarationOrInitializer.returnTypeRef.coneType
is FirExpression -> originalDestructuringDeclarationOrInitializer.coneType is FirExpression -> originalDestructuringDeclarationOrInitializer.resolvedType
else -> null else -> null
} ?: return } ?: return
@@ -154,7 +154,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
} }
} }
is ConeConstraintSystemHasContradiction -> { is ConeConstraintSystemHasContradiction -> {
val componentType = componentCall.coneType val componentType = componentCall.resolvedType
if (componentType is ConeErrorType) { if (componentType is ConeErrorType) {
// There will be other errors on this error type. // There will be other errors on this error type.
return return
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
@@ -25,7 +27,7 @@ import org.jetbrains.kotlin.fir.resolve.dfa.cfg.FunctionCallNode
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.QualifiedAccessNode import org.jetbrains.kotlin.fir.resolve.dfa.cfg.QualifiedAccessNode
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
@@ -92,7 +94,7 @@ object FirEnumCompanionInEnumConstructorCallChecker : FirClassChecker() {
private fun FirExpression.getClassSymbol(session: FirSession): FirRegularClassSymbol? { private fun FirExpression.getClassSymbol(session: FirSession): FirRegularClassSymbol? {
return when (this) { return when (this) {
is FirResolvedQualifier -> { is FirResolvedQualifier -> {
this.coneType.toRegularClassSymbol(session) this.resolvedType.toRegularClassSymbol(session)
} }
else -> (this.toReference() as? FirThisReference)?.boundSymbol else -> (this.toReference() as? FirThisReference)?.boundSymbol
} as? FirRegularClassSymbol } as? FirRegularClassSymbol
@@ -286,7 +286,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
} as? FirQualifiedAccessExpression ?: return } as? FirQualifiedAccessExpression ?: return
if (receiver.calleeReference is FirSuperReference) { if (receiver.calleeReference is FirSuperReference) {
val dispatchReceiverType = receiver.dispatchReceiver.coneType val dispatchReceiverType = receiver.dispatchReceiver.resolvedType
val classSymbol = dispatchReceiverType.toSymbol(session) ?: return val classSymbol = dispatchReceiverType.toSymbol(session) ?: return
if (!classSymbol.isDefinedInInlineFunction()) { if (!classSymbol.isDefinedInInlineFunction()) {
reporter.reportOn( reporter.reportOn(
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin import org.jetbrains.kotlin.fir.expressions.FirFunctionCallOrigin
import org.jetbrains.kotlin.fir.expressions.FirOperationNameConventions import org.jetbrains.kotlin.fir.expressions.FirOperationNameConventions
import org.jetbrains.kotlin.fir.references.toResolvedNamedFunctionSymbol import org.jetbrains.kotlin.fir.references.toResolvedNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isUnit import org.jetbrains.kotlin.fir.types.isUnit
import org.jetbrains.kotlin.fir.types.resolvedType
object FirAssignmentOperatorCallChecker : FirFunctionCallChecker() { object FirAssignmentOperatorCallChecker : FirFunctionCallChecker() {
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -25,7 +25,7 @@ object FirAssignmentOperatorCallChecker : FirFunctionCallChecker() {
) { ) {
return return
} }
if (!expression.coneType.isUnit) { if (!expression.resolvedType.isUnit) {
reporter.reportOn( reporter.reportOn(
expression.source, expression.source,
FirErrors.ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT, FirErrors.ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT,
@@ -5,16 +5,16 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.checkers.checkTypeMismatch import org.jetbrains.kotlin.fir.analysis.checkers.checkTypeMismatch
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
object FirAssignmentTypeMismatchChecker : FirVariableAssignmentChecker() { object FirAssignmentTypeMismatchChecker : FirVariableAssignmentChecker() {
override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirVariableAssignment, context: CheckerContext, reporter: DiagnosticReporter) {
val source = expression.rValue.source ?: return val source = expression.rValue.source ?: return
val coneType = expression.lValue.coneType val coneType = expression.lValue.resolvedType
checkTypeMismatch( checkTypeMismatch(
coneType, coneType,
expression, expression,
@@ -9,9 +9,9 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.CastingType import org.jetbrains.kotlin.fir.analysis.checkers.CastingType
import org.jetbrains.kotlin.fir.analysis.checkers.checkCasting
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isCastErased import org.jetbrains.kotlin.fir.analysis.checkers.isCastErased
import org.jetbrains.kotlin.fir.analysis.checkers.checkCasting
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirOperation import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
@@ -19,12 +19,13 @@ import org.jetbrains.kotlin.fir.expressions.unwrapSmartcastExpression
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.ConeDynamicType import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
object FirCastOperatorsChecker : FirTypeOperatorCallChecker() { object FirCastOperatorsChecker : FirTypeOperatorCallChecker() {
override fun check(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
val session = context.session val session = context.session
val firstArgument = expression.argumentList.arguments[0] val firstArgument = expression.argumentList.arguments[0]
val actualType = firstArgument.unwrapSmartcastExpression().coneType.fullyExpandedType(session) val actualType = firstArgument.unwrapSmartcastExpression().resolvedType.fullyExpandedType(session)
val conversionTypeRef = expression.conversionTypeRef val conversionTypeRef = expression.conversionTypeRef
val targetType = conversionTypeRef.coneType.fullyExpandedType(session) val targetType = conversionTypeRef.coneType.fullyExpandedType(session)
@@ -49,8 +49,8 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
val markedNullable = source.getChild(QUEST, depth = 1) != null val markedNullable = source.getChild(QUEST, depth = 1) != null
val isNullable = markedNullable || val isNullable = markedNullable ||
(argument as? FirResolvedQualifier)?.isNullableLHSForCallableReference == true || (argument as? FirResolvedQualifier)?.isNullableLHSForCallableReference == true ||
argument.coneType.isMarkedNullable || argument.resolvedType.isMarkedNullable ||
argument.coneType.isNullableTypeParameter(context.session.typeContext) argument.resolvedType.isNullableTypeParameter(context.session.typeContext)
if (isNullable) { if (isNullable) {
if (argument.canBeDoubleColonLHSAsType) { if (argument.canBeDoubleColonLHSAsType) {
reporter.reportOn(source, FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, context) reporter.reportOn(source, FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, context)
@@ -58,7 +58,7 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
reporter.reportOn( reporter.reportOn(
argument.source, argument.source,
FirErrors.EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, FirErrors.EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS,
argument.coneType, argument.resolvedType,
context context
) )
} }
@@ -74,7 +74,8 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
if (argument !is FirResolvedQualifier) return if (argument !is FirResolvedQualifier) return
// TODO, KT-59835: differentiate RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS // TODO, KT-59835: differentiate RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS
if (argument.typeArguments.isNotEmpty() && !argument.coneType.fullyExpandedType(context.session).isAllowedInClassLiteral(context)) { if (argument.typeArguments.isNotEmpty() && !argument.resolvedType.fullyExpandedType(context.session)
.isAllowedInClassLiteral(context)) {
val symbol = argument.symbol val symbol = argument.symbol
symbol?.lazyResolveToPhase(FirResolvePhase.TYPES) symbol?.lazyResolveToPhase(FirResolvePhase.TYPES)
@OptIn(SymbolInternals::class) @OptIn(SymbolInternals::class)
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtRealSourceElementKind import org.jetbrains.kotlin.KtRealSourceElementKind
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2 import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.collectUpperBounds import org.jetbrains.kotlin.fir.analysis.checkers.collectUpperBounds
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
import org.jetbrains.kotlin.fir.declarations.utils.isFinal import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.declarations.utils.isInline import org.jetbrains.kotlin.fir.declarations.utils.isInline
@@ -352,10 +352,10 @@ private class ArgumentInfo(
private val FirExpression.mostOriginalTypeIfSmartCast: ConeKotlinType private val FirExpression.mostOriginalTypeIfSmartCast: ConeKotlinType
get() = when (this) { get() = when (this) {
is FirSmartCastExpression -> originalExpression.mostOriginalTypeIfSmartCast is FirSmartCastExpression -> originalExpression.mostOriginalTypeIfSmartCast
else -> coneType else -> resolvedType
} }
private fun FirExpression.toArgumentInfo(context: CheckerContext) = private fun FirExpression.toArgumentInfo(context: CheckerContext) =
ArgumentInfo( ArgumentInfo(
this, coneType, mostOriginalTypeIfSmartCast.fullyExpandedType(context.session), context.session, this, resolvedType, mostOriginalTypeIfSmartCast.fullyExpandedType(context.session), context.session,
) )
@@ -25,9 +25,9 @@ import org.jetbrains.kotlin.fir.expressions.isExhaustive
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isBooleanOrNullableBoolean import org.jetbrains.kotlin.fir.types.isBooleanOrNullableBoolean
import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirExhaustiveWhenChecker : FirWhenExpressionChecker() { object FirExhaustiveWhenChecker : FirWhenExpressionChecker() {
@@ -41,7 +41,7 @@ object FirExhaustiveWhenChecker : FirWhenExpressionChecker() {
val source = whenExpression.source ?: return val source = whenExpression.source ?: return
val subjectType = whenExpression.subject?.coneType?.lowerBoundIfFlexible() val subjectType = whenExpression.subject?.resolvedType?.lowerBoundIfFlexible()
val subjectClassSymbol = subjectType?.fullyExpandedType(context.session)?.toRegularClassSymbol(context.session) val subjectClassSymbol = subjectType?.fullyExpandedType(context.session)?.toRegularClassSymbol(context.session)
if (whenExpression.usedAsExpression) { if (whenExpression.usedAsExpression) {
@@ -19,7 +19,10 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
import org.jetbrains.kotlin.fir.expressions.isExhaustive
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() { object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
@@ -56,7 +59,7 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
} }
val typeContext = context.session.typeContext val typeContext = context.session.typeContext
val returnExpressionType = resultExpression.coneType val returnExpressionType = resultExpression.resolvedType
if (!isSubtypeForTypeMismatch(typeContext, subtype = returnExpressionType, supertype = functionReturnType)) { if (!isSubtypeForTypeMismatch(typeContext, subtype = returnExpressionType, supertype = functionReturnType)) {
if (resultExpression.isNullLiteral && functionReturnType.nullability == ConeNullability.NOT_NULL) { if (resultExpression.isNullLiteral && functionReturnType.nullability == ConeNullability.NOT_NULL) {
@@ -6,16 +6,18 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirCheckNotNullCall import org.jetbrains.kotlin.fir.expressions.FirCheckNotNullCall
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.canBeNull
import org.jetbrains.kotlin.fir.types.isUnit
import org.jetbrains.kotlin.fir.types.resolvedType
object FirNotNullAssertionChecker : FirCheckNotNullCallChecker() { object FirNotNullAssertionChecker : FirCheckNotNullCallChecker() {
override fun check(expression: FirCheckNotNullCall, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirCheckNotNullCall, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -30,12 +32,12 @@ object FirNotNullAssertionChecker : FirCheckNotNullCallChecker() {
} }
// TODO: use of Unit is subject to change. // TODO: use of Unit is subject to change.
// See BodyResolveComponents.typeForQualifier in ResolveUtils.kt which returns Unit for no value type. // See BodyResolveComponents.typeForQualifier in ResolveUtils.kt which returns Unit for no value type.
if (argument is FirResolvedQualifier && argument.coneType.isUnit) { if (argument is FirResolvedQualifier && argument.resolvedType.isUnit) {
// Would be reported as NO_COMPANION_OBJECT // Would be reported as NO_COMPANION_OBJECT
return return
} }
val type = argument.coneType.fullyExpandedType(context.session) val type = argument.resolvedType.fullyExpandedType(context.session)
if (!type.canBeNull && context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) { if (!type.canBeNull && context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
reporter.reportOn(expression.source, FirErrors.UNNECESSARY_NOT_NULL_ASSERTION, type, context) reporter.reportOn(expression.source, FirErrors.UNNECESSARY_NOT_NULL_ASSERTION, type, context)
@@ -11,11 +11,14 @@ import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
object FirOptInUsageAccessChecker : FirBasicExpressionChecker() { object FirOptInUsageAccessChecker : FirBasicExpressionChecker() {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -35,7 +38,7 @@ object FirOptInUsageAccessChecker : FirBasicExpressionChecker() {
reportNotAcceptedExperimentalities(experimentalities, expression.lValue, context, reporter) reportNotAcceptedExperimentalities(experimentalities, expression.lValue, context, reporter)
} else if (expression is FirQualifiedAccessExpression) { } else if (expression is FirQualifiedAccessExpression) {
val dispatchReceiverType = val dispatchReceiverType =
expression.dispatchReceiver.takeIf { it !is FirNoReceiverExpression }?.coneType?.fullyExpandedType(context.session) expression.dispatchReceiver.takeIf { it !is FirNoReceiverExpression }?.resolvedType?.fullyExpandedType(context.session)
val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType) + val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType) +
loadExperimentalitiesFromTypeArguments(context, expression.typeArguments) loadExperimentalitiesFromTypeArguments(context, expression.typeArguments)
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.analysis.cfa.evaluatedInPlace
import org.jetbrains.kotlin.fir.analysis.cfa.requiresInitialization import org.jetbrains.kotlin.fir.analysis.cfa.requiresInitialization
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.declarations.utils.visibility
@@ -25,7 +24,7 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithCandidates
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.fir.visibilityChecker import org.jetbrains.kotlin.fir.visibilityChecker
@@ -64,7 +63,7 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
val explicitReceiver = expression.explicitReceiver val explicitReceiver = expression.explicitReceiver
// Try to get type from smartcast // Try to get type from smartcast
if (explicitReceiver is FirSmartCastExpression) { if (explicitReceiver is FirSmartCastExpression) {
val symbol = explicitReceiver.originalExpression.coneType.toRegularClassSymbol(context.session) val symbol = explicitReceiver.originalExpression.resolvedType.toRegularClassSymbol(context.session)
if (symbol != null) { if (symbol != null) {
for (declarationSymbol in symbol.declarationSymbols) { for (declarationSymbol in symbol.declarationSymbols) {
if (declarationSymbol is FirPropertySymbol && declarationSymbol.name == callableSymbol.name) { if (declarationSymbol is FirPropertySymbol && declarationSymbol.name == callableSymbol.name) {
@@ -37,7 +37,7 @@ object FirRecursiveProblemChecker : FirBasicExpressionChecker() {
} }
} }
checkConeType(expression.coneType) checkConeType(expression.resolvedType)
} }
private val FirStatement.isExpressionWithAlwaysImplicitTypeRef get() = this is FirNoReceiverExpression private val FirStatement.isExpressionWithAlwaysImplicitTypeRef get() = this is FirNoReceiverExpression
@@ -6,22 +6,22 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression import org.jetbrains.kotlin.fir.expressions.FirSpreadArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
import org.jetbrains.kotlin.fir.types.ConeFlexibleType import org.jetbrains.kotlin.fir.types.ConeFlexibleType
import org.jetbrains.kotlin.fir.types.canBeNull import org.jetbrains.kotlin.fir.types.canBeNull
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
object FirSpreadOfNullableChecker : FirFunctionCallChecker() { object FirSpreadOfNullableChecker : FirFunctionCallChecker() {
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
fun checkAndReport(argument: FirExpression, source: KtSourceElement?) { fun checkAndReport(argument: FirExpression, source: KtSourceElement?) {
val coneType = argument.coneType val coneType = argument.resolvedType
if (argument is FirSpreadArgumentExpression && coneType !is ConeFlexibleType && coneType.canBeNull) { if (argument is FirSpreadArgumentExpression && coneType !is ConeFlexibleType && coneType.canBeNull) {
reporter.reportOn(source, FirErrors.SPREAD_OF_NULLABLE, context) reporter.reportOn(source, FirErrors.SPREAD_OF_NULLABLE, context)
} }
@@ -7,19 +7,18 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.UnexpandedTypeCheck
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isUnit import org.jetbrains.kotlin.fir.types.isUnit
import org.jetbrains.kotlin.fir.types.resolvedType
object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() { object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() {
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -30,7 +29,7 @@ object FirStandaloneQualifierChecker : FirResolvedQualifierChecker() {
if (lastGetClass?.argument === expression) return if (lastGetClass?.argument === expression) return
// Note: if it's real Unit, it will be filtered by ClassKind.OBJECT check below in reportErrorOn // Note: if it's real Unit, it will be filtered by ClassKind.OBJECT check below in reportErrorOn
if (!expression.coneType.isUnit) return if (!expression.resolvedType.isUnit) return
expression.symbol.reportErrorOn(expression.source, context, reporter) expression.symbol.reportErrorOn(expression.source, context, reporter)
} }
@@ -21,9 +21,9 @@ import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
@@ -165,7 +165,7 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
expression.computeReceiversInfo(session, calledDeclarationSymbol) expression.computeReceiversInfo(session, calledDeclarationSymbol)
for (receiverExpression in listOfNotNull(dispatchReceiverExpression, extensionReceiverExpression)) { for (receiverExpression in listOfNotNull(dispatchReceiverExpression, extensionReceiverExpression)) {
if (!receiverExpression.coneType.isRestrictSuspensionReceiver(session)) continue if (!receiverExpression.resolvedType.isRestrictSuspensionReceiver(session)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionDispatchReceiverOwnerSymbol)) continue if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionDispatchReceiverOwnerSymbol)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionExtensionReceiverOwnerSymbol)) continue if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionExtensionReceiverOwnerSymbol)) continue
@@ -221,10 +221,10 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
calledDeclarationSymbol: FirCallableSymbol<*> calledDeclarationSymbol: FirCallableSymbol<*>
): Triple<FirExpression?, FirExpression?, ConeKotlinType?> { ): Triple<FirExpression?, FirExpression?, ConeKotlinType?> {
if (this is FirImplicitInvokeCall && if (this is FirImplicitInvokeCall &&
dispatchReceiver != FirNoReceiverExpression && dispatchReceiver.coneType.isSuspendOrKSuspendFunctionType(session) dispatchReceiver != FirNoReceiverExpression && dispatchReceiver.resolvedType.isSuspendOrKSuspendFunctionType(session)
) { ) {
val variableForInvoke = dispatchReceiver val variableForInvoke = dispatchReceiver
val variableForInvokeType = variableForInvoke.coneType val variableForInvokeType = variableForInvoke.resolvedType
if (!variableForInvokeType.isExtensionFunctionType) return Triple(null, null, null) if (!variableForInvokeType.isExtensionFunctionType) return Triple(null, null, null)
// `a.foo()` is resolved to invokeExtension, so it's been desugared to `foo.invoke(a)` // `a.foo()` is resolved to invokeExtension, so it's been desugared to `foo.invoke(a)`
@@ -5,20 +5,17 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirThrowExpression import org.jetbrains.kotlin.fir.expressions.FirThrowExpression
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.isSubtypeOf
import org.jetbrains.kotlin.fir.types.isTypeMismatchDueToNullability
import org.jetbrains.kotlin.fir.types.typeContext
object FirThrowExpressionTypeChecker : FirThrowExpressionChecker() { object FirThrowExpressionTypeChecker : FirThrowExpressionChecker() {
override fun check(expression: FirThrowExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirThrowExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val expectedType = context.session.builtinTypes.throwableType.coneType val expectedType = context.session.builtinTypes.throwableType.coneType
val actualType = expression.exception.coneType val actualType = expression.exception.resolvedType
if (!actualType.isSubtypeOf(expectedType, context.session)) { if (!actualType.isSubtypeOf(expectedType, context.session)) {
reporter.reportOn( reporter.reportOn(
@@ -7,25 +7,19 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.resolved
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.canBeNull import org.jetbrains.kotlin.fir.types.canBeNull
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.isUnit
object FirUnnecessarySafeCallChecker : FirSafeCallExpressionChecker() { object FirUnnecessarySafeCallChecker : FirSafeCallExpressionChecker() {
override fun check(expression: FirSafeCallExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirSafeCallExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val receiverType = expression.receiver.coneType.fullyExpandedType(context.session) val receiverType = expression.receiver.resolvedType.fullyExpandedType(context.session)
if (expression.receiver.source?.elementType == KtNodeTypes.SUPER_EXPRESSION) { if (expression.receiver.source?.elementType == KtNodeTypes.SUPER_EXPRESSION) {
reporter.reportOn(expression.source, FirErrors.UNEXPECTED_SAFE_CALL, context) reporter.reportOn(expression.source, FirErrors.UNEXPECTED_SAFE_CALL, context)
return return
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
object FirUnsupportedArrayLiteralChecker : FirArrayLiteralChecker() { object FirUnsupportedArrayLiteralChecker : FirArrayLiteralChecker() {
@@ -36,7 +36,7 @@ object FirUnsupportedArrayLiteralChecker : FirArrayLiteralChecker() {
context.callsOrAssignments.lastOrNull()?.let { context.callsOrAssignments.lastOrNull()?.let {
val arguments = when (it) { val arguments = when (it) {
is FirFunctionCall -> is FirFunctionCall ->
if (it.coneType.toRegularClassSymbol(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) { if (it.resolvedType.toRegularClassSymbol(context.session)?.classKind == ClassKind.ANNOTATION_CLASS) {
it.arguments it.arguments
} else { } else {
return false return false
@@ -6,12 +6,8 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.checkers.FirTypeRefSource import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.checkUpperBoundViolated
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.withSource
import org.jetbrains.kotlin.fir.analysis.checkers.createSubstitutorForUpperBoundViolationCheck
import org.jetbrains.kotlin.fir.analysis.checkers.toTypeArgumentsWithSourceInfo
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
@@ -45,7 +41,7 @@ object FirUpperBoundViolatedExpressionChecker : FirQualifiedAccessExpressionChec
val typeParameters: List<FirTypeParameterSymbol> val typeParameters: List<FirTypeParameterSymbol>
if (calleeSymbol is FirConstructorSymbol && calleeSymbol.isTypeAliasedConstructor) { if (calleeSymbol is FirConstructorSymbol && calleeSymbol.isTypeAliasedConstructor) {
val constructedType = expression.coneType.fullyExpandedType(context.session) val constructedType = expression.resolvedType.fullyExpandedType(context.session)
// Updating arguments with source information after expanding the type seems extremely brittle as it relies on identity equality // Updating arguments with source information after expanding the type seems extremely brittle as it relies on identity equality
// of the expression type arguments and the expanded type arguments. This cannot be applied before expanding the type because it // of the expression type arguments and the expanded type arguments. This cannot be applied before expanding the type because it
// seems like the type is already expended. // seems like the type is already expended.
@@ -6,24 +6,24 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.expressions.FirElvisExpression import org.jetbrains.kotlin.fir.expressions.FirElvisExpression
import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.canBeNull import org.jetbrains.kotlin.fir.types.canBeNull
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isNullLiteral import org.jetbrains.kotlin.fir.types.isNullLiteral
import org.jetbrains.kotlin.fir.types.resolvedType
object FirUselessElvisChecker : FirElvisExpressionChecker() { object FirUselessElvisChecker : FirElvisExpressionChecker() {
override fun check(expression: FirElvisExpression, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirElvisExpression, context: CheckerContext, reporter: DiagnosticReporter) {
// If the overall expression is not resolved/completed, the corresponding error will be reported separately. // If the overall expression is not resolved/completed, the corresponding error will be reported separately.
// See [FirControlFlowStatementsResolveTransformer#transformElvisExpression], // See [FirControlFlowStatementsResolveTransformer#transformElvisExpression],
// where an error type is recorded as the expression's return type. // where an error type is recorded as the expression's return type.
if (expression.coneType is ConeErrorType) return if (expression.resolvedType is ConeErrorType) return
val lhsType = expression.lhs.coneType val lhsType = expression.lhs.resolvedType
if (lhsType is ConeErrorType) return if (lhsType is ConeErrorType) return
if (!lhsType.canBeNull) { if (!lhsType.canBeNull) {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) { if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
@@ -23,7 +23,7 @@ object FirUselessTypeOperationCallChecker : FirTypeOperatorCallChecker() {
if (expression.operation !in FirOperation.TYPES) return if (expression.operation !in FirOperation.TYPES) return
val arg = expression.argument val arg = expression.argument
val candidateType = arg.coneType.upperBoundIfFlexible().fullyExpandedType(context.session) val candidateType = arg.resolvedType.upperBoundIfFlexible().fullyExpandedType(context.session)
if (candidateType is ConeErrorType) return if (candidateType is ConeErrorType) return
val targetType = expression.conversionTypeRef.coneType.fullyExpandedType(context.session) val targetType = expression.conversionTypeRef.coneType.fullyExpandedType(context.session)
@@ -5,18 +5,18 @@
package org.jetbrains.kotlin.fir.analysis.checkers.extended package org.jetbrains.kotlin.fir.analysis.checkers.extended
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpressionChecker
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
import org.jetbrains.kotlin.fir.expressions.FirOperation import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.name.StandardClassIds
object ArrayEqualityCanBeReplacedWithEquals : FirBasicExpressionChecker() { object ArrayEqualityCanBeReplacedWithEquals : FirBasicExpressionChecker() {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -26,8 +26,8 @@ object ArrayEqualityCanBeReplacedWithEquals : FirBasicExpressionChecker() {
val left = arguments.getOrNull(0) ?: return val left = arguments.getOrNull(0) ?: return
val right = arguments.getOrNull(1) ?: return val right = arguments.getOrNull(1) ?: return
if (left.coneType.classId != StandardClassIds.Array) return if (left.resolvedType.classId != StandardClassIds.Array) return
if (right.coneType.classId != StandardClassIds.Array) return if (right.resolvedType.classId != StandardClassIds.Array) return
reporter.reportOn(expression.source, ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS, context) reporter.reportOn(expression.source, ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS, context)
} }
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.fir.expressions.calleeReference
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isPrimitive import org.jetbrains.kotlin.fir.types.isPrimitive
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtNameReferenceExpression
@@ -39,7 +39,7 @@ object CanBeReplacedWithOperatorAssignmentChecker : FirVariableAssignmentChecker
val rValue = expression.rValue as? FirFunctionCall ?: return val rValue = expression.rValue as? FirFunctionCall ?: return
if (rValue.source?.kind is KtFakeSourceElementKind) return if (rValue.source?.kind is KtFakeSourceElementKind) return
if (rValue.explicitReceiver?.coneType?.isPrimitive != true) return if (rValue.explicitReceiver?.resolvedType?.isPrimitive != true) return
val rValueResolvedSymbol = rValue.toResolvedCallableSymbol() ?: return val rValueResolvedSymbol = rValue.toResolvedCallableSymbol() ?: return
if (rValueResolvedSymbol.dispatchReceiverClassTypeOrNull()?.isPrimitive != true) return if (rValueResolvedSymbol.dispatchReceiverClassTypeOrNull()?.isPrimitive != true) return
@@ -5,22 +5,22 @@
package org.jetbrains.kotlin.fir.analysis.checkers.extended package org.jetbrains.kotlin.fir.analysis.checkers.extended
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessExpressionChecker
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.fir.types.ConeFlexibleType import org.jetbrains.kotlin.fir.types.ConeFlexibleType
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isMarkedNullable import org.jetbrains.kotlin.fir.types.isMarkedNullable
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
object RedundantCallOfConversionMethod : FirQualifiedAccessExpressionChecker() { object RedundantCallOfConversionMethod : FirQualifiedAccessExpressionChecker() {
@@ -36,14 +36,14 @@ object RedundantCallOfConversionMethod : FirQualifiedAccessExpressionChecker() {
private fun FirExpression.isRedundant(qualifiedClassId: ClassId): Boolean { private fun FirExpression.isRedundant(qualifiedClassId: ClassId): Boolean {
val thisType = if (this is FirConstExpression<*>) { val thisType = if (this is FirConstExpression<*>) {
this.coneType.classId this.resolvedType.classId
} else { } else {
when { when {
coneType is ConeFlexibleType -> null resolvedType is ConeFlexibleType -> null
psi?.parent !is KtSafeQualifiedExpression psi?.parent !is KtSafeQualifiedExpression
&& (psi is KtSafeQualifiedExpression || coneType.isMarkedNullable) -> null && (psi is KtSafeQualifiedExpression || resolvedType.isMarkedNullable) -> null
this.coneType.isMarkedNullable -> null this.resolvedType.isMarkedNullable -> null
else -> this.coneType.classId else -> this.resolvedType.classId
} }
} }
return thisType == qualifiedClassId return thisType == qualifiedClassId
@@ -9,18 +9,18 @@ import com.intellij.lang.LighterASTNode
import com.intellij.lang.PsiBuilder import com.intellij.lang.PsiBuilder
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtLightSourceElement import org.jetbrains.kotlin.KtLightSourceElement
import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.KtPsiSourceElement
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirStringConcatenationCallChecker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirStringConcatenationCallChecker
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.FirStringConcatenationCall import org.jetbrains.kotlin.fir.expressions.FirStringConcatenationCall
import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtStringTemplateExpression import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.util.getChildren import org.jetbrains.kotlin.util.getChildren
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.util.getChildren
object RedundantSingleExpressionStringTemplateChecker : FirStringConcatenationCallChecker() { object RedundantSingleExpressionStringTemplateChecker : FirStringConcatenationCallChecker() {
override fun check(expression: FirStringConcatenationCall, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(expression: FirStringConcatenationCall, context: CheckerContext, reporter: DiagnosticReporter) {
for (argumentExpression in expression.arguments) { for (argumentExpression in expression.arguments) {
if (argumentExpression.coneType.classId == StandardClassIds.String && if (argumentExpression.resolvedType.classId == StandardClassIds.String &&
argumentExpression.stringParentChildrenCount() == 1 // there is no more children in original string template argumentExpression.stringParentChildrenCount() == 1 // there is no more children in original string template
) { ) {
reporter.reportOn(argumentExpression.source, REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE, context) reporter.reportOn(argumentExpression.source, REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE, context)
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.toResolvedNamedFunctionSymbol import org.jetbrains.kotlin.fir.references.toResolvedNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeNullability import org.jetbrains.kotlin.fir.types.ConeNullability
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
object UselessCallOnNotNullChecker : FirQualifiedAccessExpressionChecker() { object UselessCallOnNotNullChecker : FirQualifiedAccessExpressionChecker() {
@@ -37,10 +37,10 @@ object UselessCallOnNotNullChecker : FirQualifiedAccessExpressionChecker() {
} }
private fun FirExpression.getPackage(): String { private fun FirExpression.getPackage(): String {
return coneType.classId?.packageFqName.toString() return resolvedType.classId?.packageFqName.toString()
} }
private fun FirExpression.getNullability() = coneType.nullability private fun FirExpression.getNullability() = resolvedType.nullability
private val triggerOn = setOf( private val triggerOn = setOf(
@@ -1469,7 +1469,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
} }
private fun FlowContent.generate(unitExpression: FirUnitExpression) { private fun FlowContent.generate(unitExpression: FirUnitExpression) {
generate(unitExpression.coneType) generate(unitExpression.resolvedType)
} }
private fun FlowContent.generate(breakExpression: FirBreakExpression) { private fun FlowContent.generate(breakExpression: FirBreakExpression) {
@@ -1530,7 +1530,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
} }
private fun FlowContent.generate(expression: FirExpression) { private fun FlowContent.generate(expression: FirExpression) {
exprType(expression.coneType.toFirResolvedTypeRef()) { exprType(expression.resolvedType.toFirResolvedTypeRef()) {
when (expression) { when (expression) {
is FirBlock -> generateBlockIfAny(expression) is FirBlock -> generateBlockIfAny(expression)
is FirGetClassCall -> generate(expression) is FirGetClassCall -> generate(expression)
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFieldSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
@@ -158,7 +159,7 @@ internal object FirToConstantValueTransformer : FirDefaultVisitor<ConstantValue<
data.constValueProvider data.constValueProvider
)?.addEmptyVarargValuesFor(symbol) )?.addEmptyVarargValuesFor(symbol)
?: return null ?: return null
return AnnotationValue.create(qualifiedAccessExpression.coneType, mapping) return AnnotationValue.create(qualifiedAccessExpression.resolvedType, mapping)
} }
symbol.callableId.packageName.asString() == "kotlin" -> { symbol.callableId.packageName.asString() == "kotlin" -> {
@@ -11,7 +11,9 @@ import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.* import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.backend.common.actualizer.IrActualizedResult import org.jetbrains.kotlin.backend.common.actualizer.IrActualizedResult
import org.jetbrains.kotlin.builtins.StandardNames.DATA_CLASS_COMPONENT_PREFIX import org.jetbrains.kotlin.builtins.StandardNames.DATA_CLASS_COMPONENT_PREFIX
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.ValueClassRepresentation
import org.jetbrains.kotlin.diagnostics.startOffsetSkippingComments import org.jetbrains.kotlin.diagnostics.startOffsetSkippingComments
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.builder.buildFileAnnotationsContainer import org.jetbrains.kotlin.fir.builder.buildFileAnnotationsContainer
@@ -28,8 +30,11 @@ import org.jetbrains.kotlin.fir.extensions.FirExtensionApiInternals
import org.jetbrains.kotlin.fir.extensions.declarationGenerators import org.jetbrains.kotlin.fir.extensions.declarationGenerators
import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.generatedDeclarationsSymbolProvider import org.jetbrains.kotlin.fir.extensions.generatedDeclarationsSymbolProvider
import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
@@ -246,7 +251,7 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
} }
// Member fake override or bound callable reference // Member fake override or bound callable reference
dispatchReceiver !is FirNoReceiverExpression -> { dispatchReceiver !is FirNoReceiverExpression -> {
val callSiteDispatchReceiverType = dispatchReceiver.coneType val callSiteDispatchReceiverType = dispatchReceiver.resolvedType
val declarationSiteDispatchReceiverType = dispatchReceiverType val declarationSiteDispatchReceiverType = dispatchReceiverType
val type = if (callSiteDispatchReceiverType is ConeDynamicType && declarationSiteDispatchReceiverType != null) { val type = if (callSiteDispatchReceiverType is ConeDynamicType && declarationSiteDispatchReceiverType != null) {
declarationSiteDispatchReceiverType declarationSiteDispatchReceiverType
@@ -933,7 +933,7 @@ class Fir2IrDeclarationStorage(
firInitializerExpression: FirExpression?, firInitializerExpression: FirExpression?,
type: IrType? = null type: IrType? = null
): IrField = convertCatching(property) { ): IrField = convertCatching(property) {
val inferredType = type ?: firInitializerExpression!!.coneType.toIrType() val inferredType = type ?: firInitializerExpression!!.resolvedType.toIrType()
return declareIrField { symbol -> return declareIrField { symbol ->
irFactory.createField( irFactory.createField(
startOffset = startOffset, startOffset = startOffset,
@@ -1101,7 +1101,7 @@ class Fir2IrDeclarationStorage(
property.name, property.isVal, initializer, typeToUse property.name, property.isVal, initializer, typeToUse
).also { field -> ).also { field ->
if (initializer is FirConstExpression<*>) { if (initializer is FirConstExpression<*>) {
val constType = initializer.coneType.toIrType() val constType = initializer.resolvedType.toIrType()
field.initializer = factory.createExpressionBody(initializer.toIrConst(constType)) field.initializer = factory.createExpressionBody(initializer.toIrConst(constType))
} }
} }
@@ -1291,7 +1291,7 @@ class Fir2IrDeclarationStorage(
return createIrField( return createIrField(
field, field,
irParent = irClass, irParent = irClass,
type = initializer?.coneType ?: field.returnTypeRef.coneType, type = initializer?.resolvedType ?: field.returnTypeRef.coneType,
origin = IrDeclarationOrigin.DELEGATE origin = IrDeclarationOrigin.DELEGATE
).apply { ).apply {
metadata = FirMetadataSource.Field(field) metadata = FirMetadataSource.Field(field)
@@ -1467,7 +1467,7 @@ class Fir2IrDeclarationStorage(
// Note: for components call, we have to change type here (to original component type) to keep compatibility with PSI2IR // Note: for components call, we have to change type here (to original component type) to keep compatibility with PSI2IR
// Some backend optimizations related to withIndex() probably depend on this type: index should always be Int // Some backend optimizations related to withIndex() probably depend on this type: index should always be Int
// See e.g. forInStringWithIndexWithExplicitlyTypedIndexVariable.kt from codegen box tests // See e.g. forInStringWithIndexWithExplicitlyTypedIndexVariable.kt from codegen box tests
val type = ((variable.initializer as? FirComponentCall)?.coneType ?: variable.returnTypeRef.coneType).toIrType() val type = ((variable.initializer as? FirComponentCall)?.resolvedType ?: variable.returnTypeRef.coneType).toIrType()
// Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them. // Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them.
val origin = when { val origin = when {
givenOrigin != null -> givenOrigin givenOrigin != null -> givenOrigin
@@ -1509,7 +1509,7 @@ class Fir2IrDeclarationStorage(
enterScope(this) enterScope(this)
delegate = declareIrVariable( delegate = declareIrVariable(
startOffset, endOffset, IrDeclarationOrigin.PROPERTY_DELEGATE, startOffset, endOffset, IrDeclarationOrigin.PROPERTY_DELEGATE,
NameUtils.propertyDelegateName(property.name), property.delegate!!.coneType.toIrType(), NameUtils.propertyDelegateName(property.name), property.delegate!!.resolvedType.toIrType(),
isVar = false, isConst = false, isLateinit = false isVar = false, isConst = false, isLateinit = false
) )
delegate.parent = irParent delegate.parent = irParent
@@ -10,8 +10,8 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
@@ -185,7 +185,7 @@ class Fir2IrImplicitCastInserter(
} }
override fun visitThrowExpression(throwExpression: FirThrowExpression, data: IrElement): IrElement = override fun visitThrowExpression(throwExpression: FirThrowExpression, data: IrElement): IrElement =
(data as IrThrow).cast(throwExpression, throwExpression.exception.coneType, throwExpression.coneType) (data as IrThrow).cast(throwExpression, throwExpression.exception.resolvedType, throwExpression.resolvedType)
override fun visitBlock(block: FirBlock, data: IrElement): IrElement = override fun visitBlock(block: FirBlock, data: IrElement): IrElement =
(data as? IrContainerExpression)?.insertImplicitCasts() ?: data (data as? IrContainerExpression)?.insertImplicitCasts() ?: data
@@ -193,7 +193,7 @@ class Fir2IrImplicitCastInserter(
override fun visitReturnExpression(returnExpression: FirReturnExpression, data: IrElement): IrElement { override fun visitReturnExpression(returnExpression: FirReturnExpression, data: IrElement): IrElement {
val irReturn = data as? IrReturn ?: return data val irReturn = data as? IrReturn ?: return data
val expectedType = returnExpression.target.labeledElement.returnTypeRef val expectedType = returnExpression.target.labeledElement.returnTypeRef
irReturn.value = irReturn.value.cast(returnExpression.result, returnExpression.result.coneType, expectedType.coneType) irReturn.value = irReturn.value.cast(returnExpression.result, returnExpression.result.resolvedType, expectedType.coneType)
return data return data
} }
@@ -273,7 +273,7 @@ class Fir2IrImplicitCastInserter(
override fun visitSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: IrElement): IrElement { override fun visitSmartCastExpression(smartCastExpression: FirSmartCastExpression, data: IrElement): IrElement {
// We don't want an implicit cast to Nothing?. This expression just encompasses nullability after null check. // We don't want an implicit cast to Nothing?. This expression just encompasses nullability after null check.
return if (smartCastExpression.isStable && smartCastExpression.smartcastTypeWithoutNullableNothing == null) { return if (smartCastExpression.isStable && smartCastExpression.smartcastTypeWithoutNullableNothing == null) {
implicitCastOrExpression(data as IrExpression, smartCastExpression.coneType) implicitCastOrExpression(data as IrExpression, smartCastExpression.resolvedType)
} else { } else {
data as IrExpression data as IrExpression
} }
@@ -469,7 +469,7 @@ class Fir2IrVisitor(
if (initializer != null) { if (initializer != null) {
irVariable.initializer = irVariable.initializer =
convertToIrExpression(initializer) convertToIrExpression(initializer)
.insertImplicitCast(initializer, initializer.coneType, variable.returnTypeRef.coneType) .insertImplicitCast(initializer, initializer.resolvedType, variable.returnTypeRef.coneType)
} }
annotationGenerator.generate(irVariable, variable) annotationGenerator.generate(irVariable, variable)
return irVariable return irVariable
@@ -533,7 +533,7 @@ class Fir2IrVisitor(
IrVarargImpl( IrVarargImpl(
startOffset, startOffset,
endOffset, endOffset,
varargArgumentsExpression.coneType.toIrType(), varargArgumentsExpression.resolvedType.toIrType(),
varargArgumentsExpression.varargElementType.toIrType(), varargArgumentsExpression.varargElementType.toIrType(),
varargArgumentsExpression.arguments.map { it.convertToIrVarargElement() } varargArgumentsExpression.arguments.map { it.convertToIrVarargElement() }
) )
@@ -566,7 +566,7 @@ class Fir2IrVisitor(
val explicitReceiverExpression = convertToIrReceiverExpression(functionCall.explicitReceiver, functionCall.calleeReference) val explicitReceiverExpression = convertToIrReceiverExpression(functionCall.explicitReceiver, functionCall.calleeReference)
return callGenerator.convertToIrCall( return callGenerator.convertToIrCall(
functionCall, functionCall,
functionCall.coneType, functionCall.resolvedType,
explicitReceiverExpression, explicitReceiverExpression,
dynamicOperator dynamicOperator
) )
@@ -580,7 +580,7 @@ class Fir2IrVisitor(
explicitReceiverExpression.arguments.removeLast() explicitReceiverExpression.arguments.removeLast()
} }
val result = callGenerator.convertToIrCall( val result = callGenerator.convertToIrCall(
functionCall, functionCall.coneType, explicitReceiverExpression, functionCall, functionCall.resolvedType, explicitReceiverExpression,
dynamicOperator = IrDynamicOperator.EQ dynamicOperator = IrDynamicOperator.EQ
) )
if (result is IrDynamicOperatorExpression) { if (result is IrDynamicOperatorExpression) {
@@ -646,7 +646,7 @@ class Fir2IrVisitor(
qualifiedAccessExpression.explicitReceiver, qualifiedAccessExpression.calleeReference qualifiedAccessExpression.explicitReceiver, qualifiedAccessExpression.calleeReference
) )
return callGenerator.convertToIrCall( return callGenerator.convertToIrCall(
qualifiedAccessExpression, qualifiedAccessExpression.coneType, explicitReceiverExpression qualifiedAccessExpression, qualifiedAccessExpression.resolvedType, explicitReceiverExpression
) )
} }
@@ -714,7 +714,7 @@ class Fir2IrVisitor(
IrGetFieldImpl( IrGetFieldImpl(
startOffset, endOffset, contextReceivers[calleeReference.contextReceiverNumber].symbol, startOffset, endOffset, contextReceivers[calleeReference.contextReceiverNumber].symbol,
thisReceiverExpression.coneType.toIrType(), thisReceiverExpression.resolvedType.toIrType(),
thisRef, thisRef,
) )
} }
@@ -771,7 +771,7 @@ class Fir2IrVisitor(
return inaccessibleReceiverExpression.convertWithOffsets { startOffset, endOffset -> return inaccessibleReceiverExpression.convertWithOffsets { startOffset, endOffset ->
IrErrorExpressionImpl( IrErrorExpressionImpl(
startOffset, endOffset, startOffset, endOffset,
inaccessibleReceiverExpression.coneType.toIrType(), inaccessibleReceiverExpression.resolvedType.toIrType(),
"Receiver is inaccessible" "Receiver is inaccessible"
) )
} }
@@ -818,7 +818,7 @@ class Fir2IrVisitor(
} }
override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: Any?): IrElement { override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: Any?): IrElement {
return constExpression.toIrConst(constExpression.coneType.toIrType()) return constExpression.toIrConst(constExpression.resolvedType.toIrType())
} }
// ================================================================================== // ==================================================================================
@@ -873,7 +873,7 @@ class Fir2IrVisitor(
calleeReference.name != OperatorNameConventions.INVOKE && calleeReference.name != OperatorNameConventions.INVOKE &&
(calleeReference.resolvedSymbol as? FirCallableSymbol)?.callableId?.callableName == OperatorNameConventions.INVOKE (calleeReference.resolvedSymbol as? FirCallableSymbol)?.callableId?.callableName == OperatorNameConventions.INVOKE
callGenerator.convertToIrCall( callGenerator.convertToIrCall(
expression, expression.coneType, explicitReceiverExpression = null, expression, expression.resolvedType, explicitReceiverExpression = null,
variableAsFunctionMode = variableAsFunctionMode variableAsFunctionMode = variableAsFunctionMode
) )
} else { } else {
@@ -883,7 +883,7 @@ class Fir2IrVisitor(
if (expression is FirQualifiedAccessExpression && expression.calleeReference is FirSuperReference) return@run this if (expression is FirQualifiedAccessExpression && expression.calleeReference is FirSuperReference) return@run this
implicitCastInserter.implicitCastFromDispatchReceiver( implicitCastInserter.implicitCastFromDispatchReceiver(
this, expression.coneType, calleeReference, this, expression.resolvedType, calleeReference,
conversionScope.defaultConversionTypeOrigin() conversionScope.defaultConversionTypeOrigin()
) )
} }
@@ -967,7 +967,7 @@ class Fir2IrVisitor(
val receiver = statements.findFirst<FirProperty>() ?: return null val receiver = statements.findFirst<FirProperty>() ?: return null
val receiverValue = receiver.initializer ?: return null val receiverValue = receiver.initializer ?: return null
if (receiverValue.coneType !is ConeDynamicType) { if (receiverValue.resolvedType !is ConeDynamicType) {
return null return null
} }
@@ -991,7 +991,7 @@ class Fir2IrVisitor(
val arrayAccess = operationReceiver as? FirFunctionCall ?: return null val arrayAccess = operationReceiver as? FirFunctionCall ?: return null
val originalVararg = arrayAccess.resolvedArgumentMapping?.keys?.filterIsInstance<FirVarargArgumentsExpression>()?.firstOrNull() val originalVararg = arrayAccess.resolvedArgumentMapping?.keys?.filterIsInstance<FirVarargArgumentsExpression>()?.firstOrNull()
(callGenerator.convertToIrCall( (callGenerator.convertToIrCall(
arrayAccess, arrayAccess.coneType, arrayAccess, arrayAccess.resolvedType,
convertToIrReceiverExpression(receiverValue, arrayAccess.calleeReference), convertToIrReceiverExpression(receiverValue, arrayAccess.calleeReference),
noArguments = true noArguments = true
) as IrDynamicOperatorExpression).apply { ) as IrDynamicOperatorExpression).apply {
@@ -1010,12 +1010,12 @@ class Fir2IrVisitor(
} }
callGenerator.convertToIrCall( callGenerator.convertToIrCall(
qualifiedAccess, qualifiedAccess,
qualifiedAccess.coneType, qualifiedAccess.resolvedType,
convertToIrReceiverExpression(receiverExpression, qualifiedAccess.calleeReference), convertToIrReceiverExpression(receiverExpression, qualifiedAccess.calleeReference),
) )
} }
return callGenerator.convertToIrCall( return callGenerator.convertToIrCall(
operationCall, operationCall.coneType, explicitReceiverExpression operationCall, operationCall.resolvedType, explicitReceiverExpression
) )
} }
@@ -1055,7 +1055,7 @@ class Fir2IrVisitor(
val type = if (forceUnitType) val type = if (forceUnitType)
irBuiltIns.unitType irBuiltIns.unitType
else else
(lastOrNull() as? FirExpression)?.coneType?.toIrType() ?: irBuiltIns.unitType (lastOrNull() as? FirExpression)?.resolvedType?.toIrType() ?: irBuiltIns.unitType
return source.convertWithOffsets { startOffset, endOffset -> return source.convertWithOffsets { startOffset, endOffset ->
if (origin == IrStatementOrigin.DO_WHILE_LOOP) { if (origin == IrStatementOrigin.DO_WHILE_LOOP) {
IrCompositeImpl( IrCompositeImpl(
@@ -1080,7 +1080,7 @@ class Fir2IrVisitor(
return errorExpression.convertWithOffsets { startOffset, endOffset -> return errorExpression.convertWithOffsets { startOffset, endOffset ->
IrErrorExpressionImpl( IrErrorExpressionImpl(
startOffset, endOffset, startOffset, endOffset,
errorExpression.coneType.toIrType(), errorExpression.resolvedType.toIrType(),
errorExpression.diagnostic.reason errorExpression.diagnostic.reason
) )
} }
@@ -1098,7 +1098,7 @@ class Fir2IrVisitor(
source = elvisExpression.source source = elvisExpression.source
moduleData = session.moduleData moduleData = session.moduleData
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
returnTypeRef = elvisExpression.lhs.coneType.toFirResolvedTypeRef() returnTypeRef = elvisExpression.lhs.resolvedType.toFirResolvedTypeRef()
name = Name.special("<elvis>") name = Name.special("<elvis>")
initializer = elvisExpression.lhs initializer = elvisExpression.lhs
symbol = FirPropertySymbol(name) symbol = FirPropertySymbol(name)
@@ -1123,7 +1123,7 @@ class Fir2IrVisitor(
IrConstImpl.constNull(startOffset, endOffset, irBuiltIns.nothingNType) IrConstImpl.constNull(startOffset, endOffset, irBuiltIns.nothingNType)
), ),
convertToIrExpression(elvisExpression.rhs) convertToIrExpression(elvisExpression.rhs)
.insertImplicitCast(elvisExpression, elvisExpression.rhs.coneType, elvisExpression.coneType) .insertImplicitCast(elvisExpression, elvisExpression.rhs.resolvedType, elvisExpression.resolvedType)
), ),
IrElseBranchImpl( IrElseBranchImpl(
IrConstImpl.boolean(startOffset, endOffset, irBuiltIns.booleanType, true), IrConstImpl.boolean(startOffset, endOffset, irBuiltIns.booleanType, true),
@@ -1141,7 +1141,7 @@ class Fir2IrVisitor(
generateWhen( generateWhen(
startOffset, endOffset, IrStatementOrigin.ELVIS, startOffset, endOffset, IrStatementOrigin.ELVIS,
irLhsVariable, irBranches, irLhsVariable, irBranches,
elvisExpression.coneType.toIrType() elvisExpression.resolvedType.toIrType()
) )
} }
} }
@@ -1167,7 +1167,7 @@ class Fir2IrVisitor(
val whenExpressionType = val whenExpressionType =
if (whenExpression.isProperlyExhaustive && whenExpression.branches.none { if (whenExpression.isProperlyExhaustive && whenExpression.branches.none {
it.condition is FirElseIfTrueCondition && it.result.statements.isEmpty() it.condition is FirElseIfTrueCondition && it.result.statements.isEmpty()
}) whenExpression.coneType else session.builtinTypes.unitType.type }) whenExpression.resolvedType else session.builtinTypes.unitType.type
val irBranches = whenExpression.branches.mapTo(mutableListOf()) { branch -> val irBranches = whenExpression.branches.mapTo(mutableListOf()) { branch ->
branch.toIrWhenBranch(whenExpressionType) branch.toIrWhenBranch(whenExpressionType)
} }
@@ -1221,7 +1221,7 @@ class Fir2IrVisitor(
private fun FirWhenBranch.toIrWhenBranch(whenExpressionType: ConeKotlinType): IrBranch { private fun FirWhenBranch.toIrWhenBranch(whenExpressionType: ConeKotlinType): IrBranch {
return convertWithOffsets { startOffset, endOffset -> return convertWithOffsets { startOffset, endOffset ->
val condition = condition val condition = condition
val irResult = convertToIrExpression(result).insertImplicitCast(result, result.coneType, whenExpressionType) val irResult = convertToIrExpression(result).insertImplicitCast(result, result.resolvedType, whenExpressionType)
if (condition is FirElseIfTrueCondition) { if (condition is FirElseIfTrueCondition) {
IrElseBranchImpl(IrConstImpl.boolean(irResult.startOffset, irResult.endOffset, irBuiltIns.booleanType, true), irResult) IrElseBranchImpl(IrConstImpl.boolean(irResult.startOffset, irResult.endOffset, irBuiltIns.booleanType, true), irResult)
} else { } else {
@@ -1359,7 +1359,7 @@ class Fir2IrVisitor(
// that line number for the finally block. // that line number for the finally block.
return tryExpression.convertWithOffsets { startOffset, endOffset -> return tryExpression.convertWithOffsets { startOffset, endOffset ->
IrTryImpl( IrTryImpl(
startOffset, endOffset, tryExpression.coneType.toIrType(), startOffset, endOffset, tryExpression.resolvedType.toIrType(),
tryExpression.tryBlock.convertToIrBlock(forceUnitType = false), tryExpression.tryBlock.convertToIrBlock(forceUnitType = false),
tryExpression.catches.map { it.accept(this, data) as IrCatch }, tryExpression.catches.map { it.accept(this, data) as IrCatch },
tryExpression.finallyBlock?.convertToIrBlock(forceUnitType = true) tryExpression.finallyBlock?.convertToIrBlock(forceUnitType = true)
@@ -1443,13 +1443,13 @@ class Fir2IrVisitor(
return checkNotNullCall.convertWithOffsets { startOffset, endOffset -> return checkNotNullCall.convertWithOffsets { startOffset, endOffset ->
IrCallImpl( IrCallImpl(
startOffset, endOffset, startOffset, endOffset,
checkNotNullCall.coneType.toIrType(), checkNotNullCall.resolvedType.toIrType(),
irBuiltIns.checkNotNullSymbol, irBuiltIns.checkNotNullSymbol,
typeArgumentsCount = 1, typeArgumentsCount = 1,
valueArgumentsCount = 1, valueArgumentsCount = 1,
origin = IrStatementOrigin.EXCLEXCL origin = IrStatementOrigin.EXCLEXCL
).apply { ).apply {
putTypeArgument(0, checkNotNullCall.argument.coneType.toIrType().makeNotNull()) putTypeArgument(0, checkNotNullCall.argument.resolvedType.toIrType().makeNotNull())
putValueArgument(0, convertToIrExpression(checkNotNullCall.argument)) putValueArgument(0, convertToIrExpression(checkNotNullCall.argument))
} }
} }
@@ -1457,12 +1457,12 @@ class Fir2IrVisitor(
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Any?): IrElement = whileAnalysing(session, getClassCall) { override fun visitGetClassCall(getClassCall: FirGetClassCall, data: Any?): IrElement = whileAnalysing(session, getClassCall) {
val argument = getClassCall.argument val argument = getClassCall.argument
val irType = getClassCall.coneType.toIrType() val irType = getClassCall.resolvedType.toIrType()
val irClassType = val irClassType =
if (argument is FirClassReferenceExpression) { if (argument is FirClassReferenceExpression) {
argument.classTypeRef.toIrType() argument.classTypeRef.toIrType()
} else { } else {
argument.coneType.toIrType() argument.resolvedType.toIrType()
} }
val irClassReferenceSymbol = when (argument) { val irClassReferenceSymbol = when (argument) {
is FirResolvedReifiedParameterReference -> { is FirResolvedReifiedParameterReference -> {
@@ -1510,7 +1510,7 @@ class Fir2IrVisitor(
private fun convertToArrayLiteral(arrayLiteral: FirArrayLiteral): IrVararg { private fun convertToArrayLiteral(arrayLiteral: FirArrayLiteral): IrVararg {
return arrayLiteral.convertWithOffsets { startOffset, endOffset -> return arrayLiteral.convertWithOffsets { startOffset, endOffset ->
val arrayType = arrayLiteral.coneType.toIrType() val arrayType = arrayLiteral.resolvedType.toIrType()
val elementType = if (arrayLiteral.coneTypeOrNull != null) { val elementType = if (arrayLiteral.coneTypeOrNull != null) {
arrayType.getArrayElementType(irBuiltIns) arrayType.getArrayElementType(irBuiltIns)
} else { } else {
@@ -9,8 +9,8 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.StandardClassIds
class PrimitiveConeNumericComparisonInfo( class PrimitiveConeNumericComparisonInfo(
val comparisonType: ConeClassLikeType, val comparisonType: ConeClassLikeType,
@@ -28,8 +28,8 @@ fun FirComparisonExpression.inferPrimitiveNumericComparisonInfo(): PrimitiveCone
inferPrimitiveNumericComparisonInfo(left, right) inferPrimitiveNumericComparisonInfo(left, right)
fun inferPrimitiveNumericComparisonInfo(left: FirExpression, right: FirExpression): PrimitiveConeNumericComparisonInfo? { fun inferPrimitiveNumericComparisonInfo(left: FirExpression, right: FirExpression): PrimitiveConeNumericComparisonInfo? {
val leftType = left.coneType val leftType = left.resolvedType
val rightType = right.coneType val rightType = right.resolvedType
val leftPrimitiveOrNullableType = leftType.getPrimitiveTypeOrSupertype() ?: return null val leftPrimitiveOrNullableType = leftType.getPrimitiveTypeOrSupertype() ?: return null
val rightPrimitiveOrNullableType = rightType.getPrimitiveTypeOrSupertype() ?: return null val rightPrimitiveOrNullableType = rightType.getPrimitiveTypeOrSupertype() ?: return null
val leastCommonType = leastCommonPrimitiveNumericType(leftPrimitiveOrNullableType, rightPrimitiveOrNullableType) val leastCommonType = leastCommonPrimitiveNumericType(leftPrimitiveOrNullableType, rightPrimitiveOrNullableType)
@@ -450,7 +450,7 @@ internal class AdapterGenerator(
if (!samType.isSamType) return this if (!samType.isSamType) return this
return IrTypeOperatorCallImpl( return IrTypeOperatorCallImpl(
this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType, this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType,
castArgumentToFunctionalInterfaceForSamType(this, argument.coneType, samFirType) castArgumentToFunctionalInterfaceForSamType(this, argument.resolvedType, samFirType)
) )
} }
@@ -556,7 +556,7 @@ internal class AdapterGenerator(
session.typeContext.newTypeCheckerState( session.typeContext.newTypeCheckerState(
errorTypesEqualToAnything = false, stubTypesEqualToAnything = true errorTypesEqualToAnything = false, stubTypesEqualToAnything = true
), ),
argument.coneType, argument.resolvedType,
parameter.returnTypeRef.coneType, parameter.returnTypeRef.coneType,
isFromNullabilityConstraint = true isFromNullabilityConstraint = true
) )
@@ -638,7 +638,7 @@ internal class AdapterGenerator(
expectedFunctionalType: ConeClassLikeType, expectedFunctionalType: ConeClassLikeType,
argument: FirExpression argument: FirExpression
): IrSimpleFunctionSymbol? { ): IrSimpleFunctionSymbol? {
val argumentType = argument.coneType val argumentType = argument.resolvedType
val argumentTypeWithInvoke = argumentType.findSubtypeOfBasicFunctionType(session, expectedFunctionalType) ?: return null val argumentTypeWithInvoke = argumentType.findSubtypeOfBasicFunctionType(session, expectedFunctionalType) ?: return null
return if (argumentTypeWithInvoke.isSomeFunctionType(session)) { return if (argumentTypeWithInvoke.isSomeFunctionType(session)) {
@@ -73,7 +73,7 @@ class CallAndReferenceGenerator(
explicitReceiverExpression: IrExpression?, explicitReceiverExpression: IrExpression?,
isDelegate: Boolean isDelegate: Boolean
): IrExpression { ): IrExpression {
val type = approximateFunctionReferenceType(callableReferenceAccess.coneType).toIrType() val type = approximateFunctionReferenceType(callableReferenceAccess.resolvedType).toIrType()
val callableSymbol = callableReferenceAccess.calleeReference.toResolvedCallableSymbol() val callableSymbol = callableReferenceAccess.calleeReference.toResolvedCallableSymbol()
if (callableSymbol?.origin == FirDeclarationOrigin.SamConstructor) { if (callableSymbol?.origin == FirDeclarationOrigin.SamConstructor) {
@@ -106,7 +106,7 @@ class CallAndReferenceGenerator(
val referencedProperty = symbol.owner val referencedProperty = symbol.owner
val referencedPropertyGetter = referencedProperty.getter val referencedPropertyGetter = referencedProperty.getter
val referencedPropertySetterSymbol = val referencedPropertySetterSymbol =
if (callableReferenceAccess.coneType.isKMutableProperty(session)) referencedProperty.setter?.symbol if (callableReferenceAccess.resolvedType.isKMutableProperty(session)) referencedProperty.setter?.symbol
else null else null
val backingFieldSymbol = when { val backingFieldSymbol = when {
referencedPropertyGetter != null -> null referencedPropertyGetter != null -> null
@@ -163,7 +163,7 @@ class CallAndReferenceGenerator(
// Receivers are being applied inside // Receivers are being applied inside
with(adapterGenerator) { with(adapterGenerator) {
// TODO: Figure out why `adaptedType` is different from the `type`? // TODO: Figure out why `adaptedType` is different from the `type`?
val adaptedType = callableReferenceAccess.coneType.toIrType() as IrSimpleType val adaptedType = callableReferenceAccess.resolvedType.toIrType() as IrSimpleType
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType) generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType)
} }
} else { } else {
@@ -791,13 +791,13 @@ class CallAndReferenceGenerator(
qualifier: FirResolvedQualifier, qualifier: FirResolvedQualifier,
callableReferenceAccess: FirCallableReferenceAccess? callableReferenceAccess: FirCallableReferenceAccess?
): IrExpression? { ): IrExpression? {
val classSymbol = (qualifier.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session) val classSymbol = (qualifier.resolvedType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)
if (callableReferenceAccess?.isBound == false) { if (callableReferenceAccess?.isBound == false) {
return null return null
} }
val irType = qualifier.coneType.toIrType() val irType = qualifier.resolvedType.toIrType()
return qualifier.convertWithOffsets { startOffset, endOffset -> return qualifier.convertWithOffsets { startOffset, endOffset ->
if (classSymbol != null) { if (classSymbol != null) {
IrGetObjectValueImpl( IrGetObjectValueImpl(
@@ -1010,7 +1010,7 @@ class CallAndReferenceGenerator(
var irArgument = visitor.convertToIrExpression(argument) var irArgument = visitor.convertToIrExpression(argument)
if (parameter != null) { if (parameter != null) {
with(visitor.implicitCastInserter) { with(visitor.implicitCastInserter) {
irArgument = irArgument.cast(argument, argument.coneType, parameter.returnTypeRef.coneType) irArgument = irArgument.cast(argument, argument.resolvedType, parameter.returnTypeRef.coneType)
} }
} }
with(adapterGenerator) { with(adapterGenerator) {
@@ -1088,7 +1088,7 @@ class CallAndReferenceGenerator(
) )
if (conversionFunctions.isNotEmpty()) { if (conversionFunctions.isNotEmpty()) {
elements.forEachIndexed { i, irVarargElement -> elements.forEachIndexed { i, irVarargElement ->
val targetFun = argument.arguments[i].coneType.toIrType().classifierOrNull?.let { conversionFunctions[it] } val targetFun = argument.arguments[i].resolvedType.toIrType().classifierOrNull?.let { conversionFunctions[it] }
if (targetFun != null && irVarargElement is IrExpression) { if (targetFun != null && irVarargElement is IrExpression) {
elements[i] = elements[i] =
irVarargElement.applyToElement(argument.arguments[i], targetFun) irVarargElement.applyToElement(argument.arguments[i], targetFun)
@@ -1103,7 +1103,7 @@ class CallAndReferenceGenerator(
Name.identifier("to" + targetTypeFqName.shortName().asString()), Name.identifier("to" + targetTypeFqName.shortName().asString()),
StandardNames.BUILT_INS_PACKAGE_NAME.asString() StandardNames.BUILT_INS_PACKAGE_NAME.asString()
) )
val sourceTypeClassifier = argument.coneType.toIrType().classifierOrNull ?: return this val sourceTypeClassifier = argument.resolvedType.toIrType().classifierOrNull ?: return this
val conversionFunction = conversionFunctions[sourceTypeClassifier] ?: return this val conversionFunction = conversionFunctions[sourceTypeClassifier] ?: return this
@@ -1251,7 +1251,7 @@ class CallAndReferenceGenerator(
with(visitor.implicitCastInserter) { with(visitor.implicitCastInserter) {
it.cast( it.cast(
qualifiedAccess.extensionReceiver, qualifiedAccess.extensionReceiver,
qualifiedAccess.extensionReceiver.coneType, qualifiedAccess.extensionReceiver.resolvedType,
receiverType.coneType, receiverType.coneType,
) )
} }
@@ -268,7 +268,11 @@ internal class ClassMemberGenerator(
val irExpression = visitor.convertToIrExpression(initializerExpression, isDelegate = property.delegate != null) val irExpression = visitor.convertToIrExpression(initializerExpression, isDelegate = property.delegate != null)
if (property.delegate == null) { if (property.delegate == null) {
with(visitor.implicitCastInserter) { with(visitor.implicitCastInserter) {
irExpression.cast(initializerExpression, initializerExpression.coneType, property.returnTypeRef.coneType) irExpression.cast(
initializerExpression,
initializerExpression.resolvedType,
property.returnTypeRef.coneType
)
} }
} else { } else {
irExpression irExpression
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
@@ -91,7 +92,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
memberRequiredPhase = null, memberRequiredPhase = null,
) )
val delegateToScope = firField.initializer!!.coneType val delegateToScope = firField.initializer!!.resolvedType
.fullyExpandedType(session) .fullyExpandedType(session)
.lowerBoundIfFlexible() .lowerBoundIfFlexible()
.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, null) ?: return .scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, null) ?: return
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.fir.backend.generators
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.types.ConeDynamicType import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isMarkedNullable import org.jetbrains.kotlin.fir.types.isMarkedNullable
import org.jetbrains.kotlin.fir.types.isNullable import org.jetbrains.kotlin.fir.types.isNullable
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.ir.builders.primitiveOp1 import org.jetbrains.kotlin.ir.builders.primitiveOp1
import org.jetbrains.kotlin.ir.builders.primitiveOp2 import org.jetbrains.kotlin.ir.builders.primitiveOp2
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
@@ -46,7 +46,7 @@ internal class OperatorExpressionGenerator(
val operation = comparisonExpression.operation val operation = comparisonExpression.operation
val receiver = comparisonExpression.compareToCall.explicitReceiver val receiver = comparisonExpression.compareToCall.explicitReceiver
if (receiver?.coneType is ConeDynamicType) { if (receiver?.resolvedType is ConeDynamicType) {
val dynamicOperator = operation.toIrDynamicOperator() val dynamicOperator = operation.toIrDynamicOperator()
?: throw Exception("Can't convert to the corresponding IrDynamicOperator") ?: throw Exception("Can't convert to the corresponding IrDynamicOperator")
val argument = comparisonExpression.compareToCall.dynamicVarargArguments?.firstOrNull() val argument = comparisonExpression.compareToCall.dynamicVarargArguments?.firstOrNull()
@@ -241,7 +241,7 @@ internal class OperatorExpressionGenerator(
comparisonInfo: PrimitiveConeNumericComparisonInfo?, comparisonInfo: PrimitiveConeNumericComparisonInfo?,
isLeftType: Boolean isLeftType: Boolean
): IrExpression { ): IrExpression {
val isOriginalNullable = (this as? FirSmartCastExpression)?.originalExpression?.coneType?.isMarkedNullable ?: false val isOriginalNullable = (this as? FirSmartCastExpression)?.originalExpression?.resolvedType?.isMarkedNullable ?: false
val irExpression = visitor.convertToIrExpression(this) val irExpression = visitor.convertToIrExpression(this)
val operandType = if (isLeftType) comparisonInfo?.leftType else comparisonInfo?.rightType val operandType = if (isLeftType) comparisonInfo?.leftType else comparisonInfo?.rightType
val targetType = comparisonInfo?.comparisonType val targetType = comparisonInfo?.comparisonType
@@ -10,7 +10,8 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.isAnnotationClass import org.jetbrains.kotlin.descriptors.isAnnotationClass
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
@@ -18,12 +19,11 @@ import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.Fir2IrPropertySymbol import org.jetbrains.kotlin.fir.symbols.Fir2IrPropertySymbol
import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
@@ -98,7 +98,7 @@ class Fir2IrLazyProperty(
containingClass?.classKind?.isAnnotationClass == true -> initializer?.asCompileTimeIrInitializer(components) containingClass?.classKind?.isAnnotationClass == true -> initializer?.asCompileTimeIrInitializer(components)
// Setting initializers to every other class causes some cryptic errors in lowerings // Setting initializers to every other class causes some cryptic errors in lowerings
initializer is FirConstExpression<*> -> { initializer is FirConstExpression<*> -> {
val constType = with(typeConverter) { initializer.coneType.toIrType() } val constType = with(typeConverter) { initializer.resolvedType.toIrType() }
factory.createExpressionBody(initializer.toIrConst(constType)) factory.createExpressionBody(initializer.toIrConst(constType))
} }
else -> null else -> null
@@ -95,7 +95,7 @@ internal class AnnotationsLoader(private val session: FirSession, private val ko
visitExpression(name, buildArrayLiteral { visitExpression(name, buildArrayLiteral {
guessArrayTypeIfNeeded(name, elements)?.let { guessArrayTypeIfNeeded(name, elements)?.let {
coneTypeOrNull = it.coneTypeOrNull coneTypeOrNull = it.coneTypeOrNull
} ?: elements.firstOrNull()?.coneType?.createOutArrayType()?.let { } ?: elements.firstOrNull()?.resolvedType?.createOutArrayType()?.let {
coneTypeOrNull = it coneTypeOrNull = it
} }
argumentList = buildArgumentList { argumentList = buildArgumentList {
@@ -84,7 +84,7 @@ fun List<FirAnnotation>.computeTypeAttributes(
for (annotation in this) { for (annotation in this) {
val classId = when (shouldExpandTypeAliases) { val classId = when (shouldExpandTypeAliases) {
true -> annotation.tryExpandClassId(session) true -> annotation.tryExpandClassId(session)
false -> annotation.coneType.classId false -> annotation.resolvedType.classId
} }
when (classId) { when (classId) {
CompilerConeAttributes.Exact.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.Exact CompilerConeAttributes.Exact.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.Exact
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
import org.jetbrains.kotlin.fir.expressions.toReference import org.jetbrains.kotlin.fir.expressions.toReference
@@ -287,7 +286,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
val dispatchReceiverParameterClassLookupTag = dispatchReceiverParameterClassSymbol.toLookupTag() val dispatchReceiverParameterClassLookupTag = dispatchReceiverParameterClassSymbol.toLookupTag()
val dispatchReceiverValueOwnerLookupTag = val dispatchReceiverValueOwnerLookupTag =
dispatchReceiver.coneType.findClassRepresentation( dispatchReceiver.resolvedType.findClassRepresentation(
dispatchReceiverParameterClassLookupTag.constructClassType( dispatchReceiverParameterClassLookupTag.constructClassType(
Array(dispatchReceiverParameterClassSymbol.fir.typeParameters.size) { ConeStarProjection }, Array(dispatchReceiverParameterClassSymbol.fir.typeParameters.size) { ConeStarProjection },
isNullable = true isNullable = true
@@ -364,10 +363,10 @@ abstract class FirVisibilityChecker : FirSessionComponent {
session: FirSession session: FirSession
): Boolean { ): Boolean {
if (dispatchReceiver == null) return true if (dispatchReceiver == null) return true
var dispatchReceiverType = dispatchReceiver.coneType var dispatchReceiverType = dispatchReceiver.resolvedType
if (dispatchReceiver is FirPropertyAccessExpression && dispatchReceiver.calleeReference is FirSuperReference) { if (dispatchReceiver is FirPropertyAccessExpression && dispatchReceiver.calleeReference is FirSuperReference) {
// Special 'super' case: type of this, not of super, should be taken for the check below // Special 'super' case: type of this, not of super, should be taken for the check below
dispatchReceiverType = dispatchReceiver.dispatchReceiver.coneType dispatchReceiverType = dispatchReceiver.dispatchReceiver.resolvedType
} }
val typeCheckerState = session.typeContext.newTypeCheckerState( val typeCheckerState = session.typeContext.newTypeCheckerState(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
@@ -394,7 +393,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
private fun FirExpression?.ownerIfCompanion(session: FirSession): ConeClassLikeLookupTag? = private fun FirExpression?.ownerIfCompanion(session: FirSession): ConeClassLikeLookupTag? =
// TODO: what if there is an intersection type from smartcast? // TODO: what if there is an intersection type from smartcast?
(this?.coneType as? ConeClassLikeType)?.lookupTag?.ownerIfCompanion(session) (this?.resolvedType as? ConeClassLikeType)?.lookupTag?.ownerIfCompanion(session)
// monitorEnter/monitorExit are the only functions which are accessed "illegally" (see kotlin/util/Synchronized.kt). // monitorEnter/monitorExit are the only functions which are accessed "illegally" (see kotlin/util/Synchronized.kt).
// Since they are intrinsified in the codegen, FIR should treat it as visible. // Since they are intrinsified in the codegen, FIR should treat it as visible.
@@ -508,7 +507,7 @@ private fun FirMemberDeclaration.containingNonLocalClass(
if (dispatchReceiver != null) { if (dispatchReceiver != null) {
val baseReceiverType = dispatchReceiverClassTypeOrNull() val baseReceiverType = dispatchReceiverClassTypeOrNull()
if (baseReceiverType != null) { if (baseReceiverType != null) {
dispatchReceiver.coneType.findClassRepresentation(baseReceiverType, session)?.toSymbol(session)?.fir?.let { dispatchReceiver.resolvedType.findClassRepresentation(baseReceiverType, session)?.toSymbol(session)?.fir?.let {
return it return it
} }
} }
@@ -240,7 +240,7 @@ fun FirAnnotation.getKClassArgument(name: Name): ConeKotlinType? {
} }
fun FirGetClassCall.getTargetType(): ConeKotlinType? { fun FirGetClassCall.getTargetType(): ConeKotlinType? {
return coneType.typeArguments.getOrNull(0)?.type return resolvedType.typeArguments.getOrNull(0)?.type
} }
fun FirAnnotationContainer.getJvmNameFromAnnotation(session: FirSession, target: AnnotationUseSiteTarget? = null): String? { fun FirAnnotationContainer.getJvmNameFromAnnotation(session: FirSession, target: AnnotationUseSiteTarget? = null): String? {
@@ -41,7 +41,7 @@ fun FirSmartCastExpression.smartcastScope(
return smartcastScope return smartcastScope
} }
val originalScope = originalExpression.coneType.scope( val originalScope = originalExpression.resolvedType.scope(
useSiteSession = useSiteSession, useSiteSession = useSiteSession,
scopeSession = scopeSession, scopeSession = scopeSession,
fakeOverrideTypeCalculator = FakeOverrideTypeCalculator.DoNothing, fakeOverrideTypeCalculator = FakeOverrideTypeCalculator.DoNothing,
@@ -585,7 +585,7 @@ class FirCallResolver(
//calleeReference and annotationTypeRef are both error nodes so we need to avoid doubling of the diagnostic report //calleeReference and annotationTypeRef are both error nodes so we need to avoid doubling of the diagnostic report
else ConeStubDiagnostic( else ConeStubDiagnostic(
//prefer diagnostic with symbol, e.g. to use the symbol during navigation in IDE //prefer diagnostic with symbol, e.g. to use the symbol during navigation in IDE
(annotation.coneType as? ConeErrorType)?.diagnostic as? ConeDiagnosticWithSymbol<*> (annotation.resolvedType as? ConeErrorType)?.diagnostic as? ConeDiagnosticWithSymbol<*>
?: ConeUnresolvedNameError(reference.name)), ?: ConeUnresolvedNameError(reference.name)),
reference.source reference.source
) )
@@ -722,7 +722,7 @@ class FirCallResolver(
ConeResolutionToClassifierError(singleExpectedCandidate!!, fir.symbol) ConeResolutionToClassifierError(singleExpectedCandidate!!, fir.symbol)
} }
else -> { else -> {
val coneType = explicitReceiver?.coneType val coneType = explicitReceiver?.resolvedType
when { when {
coneType != null && !coneType.isUnit -> { coneType != null && !coneType.isUnit -> {
ConeFunctionExpectedError( ConeFunctionExpectedError(
@@ -751,7 +751,7 @@ class FirCallResolver(
name.asString() == "invoke" && explicitReceiver is FirConstExpression<*> -> name.asString() == "invoke" && explicitReceiver is FirConstExpression<*> ->
ConeFunctionExpectedError( ConeFunctionExpectedError(
explicitReceiver.value?.toString() ?: "", explicitReceiver.value?.toString() ?: "",
explicitReceiver.coneType, explicitReceiver.resolvedType,
) )
reference is FirSuperReference && (reference.superTypeRef.firClassLike(session) as? FirClass)?.isInterface == true -> ConeNoConstructorError reference is FirSuperReference && (reference.superTypeRef.firClassLike(session) as? FirClass)?.isInterface == true -> ConeNoConstructorError
else -> ConeUnresolvedNameError(name) else -> ConeUnresolvedNameError(name)
@@ -119,7 +119,7 @@ class FirDoubleColonExpressionResolver(private val session: FirSession) {
} }
private fun resolveExpressionOnLHS(expression: FirExpression): DoubleColonLHS.Expression? { private fun resolveExpressionOnLHS(expression: FirExpression): DoubleColonLHS.Expression? {
val type = expression.coneType val type = expression.resolvedType
if (expression is FirResolvedQualifier) { if (expression is FirResolvedQualifier) {
val firClass = expression.expandedRegularClassIfAny() ?: return null val firClass = expression.expandedRegularClassIfAny() ?: return null
@@ -414,7 +414,7 @@ private fun <T : FirExpression> BodyResolveComponents.transformExpressionUsingSm
SmartcastStability.STABLE_VALUE SmartcastStability.STABLE_VALUE
} }
val originalType = expression.coneType.fullyExpandedType(session) val originalType = expression.resolvedType.fullyExpandedType(session)
val allTypes = typesFromSmartCast.also { val allTypes = typesFromSmartCast.also {
if (originalType !is ConeStubType) { if (originalType !is ConeStubType) {
it += originalType.fullyExpandedType(session) it += originalType.fullyExpandedType(session)
@@ -147,7 +147,7 @@ private fun Candidate.resolveBlockArgument(
checkApplicabilityForArgumentType( checkApplicabilityForArgumentType(
csBuilder, csBuilder,
block, block,
block.coneType, block.resolvedType,
expectedType?.type, expectedType?.type,
SimpleConstraintSystemConstraintPosition, SimpleConstraintSystemConstraintPosition,
isReceiver = false, isReceiver = false,
@@ -513,7 +513,7 @@ private fun getExpectedTypeWithImplicintIntegerCoercion(
val argumentType = val argumentType =
if (argument.isIntegerLiteralOrOperatorCall()) { if (argument.isIntegerLiteralOrOperatorCall()) {
if (candidateExpectedType.fullyExpandedType(session).isUnsignedTypeOrNullableUnsignedType) if (candidateExpectedType.fullyExpandedType(session).isUnsignedTypeOrNullableUnsignedType)
argument.coneType argument.resolvedType
else null else null
} else { } else {
argument.calleeReference?.toResolvedCallableSymbol()?.takeIf { argument.calleeReference?.toResolvedCallableSymbol()?.takeIf {
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzerContext import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzerContext
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
@@ -135,7 +136,7 @@ class CandidateFactory private constructor(
private fun FirExpression?.isCandidateFromCompanionObjectTypeScope(useSiteSession: FirSession): Boolean { private fun FirExpression?.isCandidateFromCompanionObjectTypeScope(useSiteSession: FirSession): Boolean {
val resolvedQualifier = this as? FirResolvedQualifier ?: return false val resolvedQualifier = this as? FirResolvedQualifier ?: return false
val originClassOfCandidate = this.coneType.classId ?: return false val originClassOfCandidate = this.resolvedType.classId ?: return false
val companion = resolvedQualifier.symbol?.fullyExpandedClass(useSiteSession)?.fir?.companionObjectSymbol val companion = resolvedQualifier.symbol?.fullyExpandedClass(useSiteSession)?.fir?.companionObjectSymbol
return companion?.classId == originClassOfCandidate return companion?.classId == originClassOfCandidate
} }
@@ -25,7 +25,10 @@ import org.jetbrains.kotlin.fir.resolve.inference.csBuilder
import org.jetbrains.kotlin.fir.resolve.inference.hasBuilderInferenceAnnotation import org.jetbrains.kotlin.fir.resolve.inference.hasBuilderInferenceAnnotation
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExplicitTypeParameterConstraintPosition import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExplicitTypeParameterConstraintPosition
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -137,7 +140,7 @@ private fun Candidate.prepareReceivers(
context: ResolutionContext, context: ResolutionContext,
): ReceiverDescription { ): ReceiverDescription {
val argumentType = captureFromTypeParameterUpperBoundIfNeeded( val argumentType = captureFromTypeParameterUpperBoundIfNeeded(
argumentType = argumentExtensionReceiver.coneType, argumentType = argumentExtensionReceiver.resolvedType,
expectedType = expectedType, expectedType = expectedType,
session = context.session session = context.session
).let { prepareCapturedType(it, context) } ).let { prepareCapturedType(it, context) }
@@ -160,7 +163,7 @@ object CheckDispatchReceiver : ResolutionStage() {
} }
} }
val dispatchReceiverValueType = candidate.dispatchReceiver?.coneType ?: return val dispatchReceiverValueType = candidate.dispatchReceiver?.resolvedType ?: return
val isReceiverNullable = !AbstractNullabilityChecker.isSubtypeOfAny(context.session.typeContext, dispatchReceiverValueType) val isReceiverNullable = !AbstractNullabilityChecker.isSubtypeOfAny(context.session.typeContext, dispatchReceiverValueType)
val isCandidateFromUnstableSmartcast = val isCandidateFromUnstableSmartcast =
@@ -187,7 +190,10 @@ object CheckDispatchReceiver : ResolutionStage() {
UnstableSmartCast( UnstableSmartCast(
smartcastedReceiver, smartcastedReceiver,
targetType, targetType,
context.session.typeContext.isTypeMismatchDueToNullability(smartcastedReceiver.originalExpression.coneType, targetType) context.session.typeContext.isTypeMismatchDueToNullability(
smartcastedReceiver.originalExpression.resolvedType,
targetType
)
) )
) )
} else if (isReceiverNullable) { } else if (isReceiverNullable) {
@@ -269,7 +275,7 @@ object CheckDslScopeViolation : ResolutionStage() {
candidate, candidate,
sink, sink,
context, context,
{ getDslMarkersOfImplicitReceiver(thisReference.boundSymbol, receiver.coneType, context) } { getDslMarkersOfImplicitReceiver(thisReference.boundSymbol, receiver.resolvedType, context) }
) { ) {
// Here we rely on the fact that receiver expression of implicit receiver value can not be changed // Here we rely on the fact that receiver expression of implicit receiver value can not be changed
// during resolution of one single call // during resolution of one single call
@@ -307,7 +313,7 @@ object CheckDslScopeViolation : ResolutionStage() {
// ``` // ```
// `useX()` is a call to `invoke` with `useX` as the dispatch receiver. In the FIR tree, extension receiver is represented as an // `useX()` is a call to `invoke` with `useX` as the dispatch receiver. In the FIR tree, extension receiver is represented as an
// implicit `this` expression passed as the first argument. // implicit `this` expression passed as the first argument.
if (candidate.dispatchReceiver?.coneType?.fullyExpandedType(context.session)?.isSomeFunctionType(context.session) == true && if (candidate.dispatchReceiver?.resolvedType?.fullyExpandedType(context.session)?.isSomeFunctionType(context.session) == true &&
(candidate.symbol as? FirNamedFunctionSymbol)?.name == OperatorNameConventions.INVOKE (candidate.symbol as? FirNamedFunctionSymbol)?.name == OperatorNameConventions.INVOKE
) { ) {
val firstArg = candidate.argumentMapping?.keys?.firstOrNull() as? FirThisReceiverExpression ?: return val firstArg = candidate.argumentMapping?.keys?.firstOrNull() as? FirThisReceiverExpression ?: return
@@ -376,7 +382,7 @@ object CheckDslScopeViolation : ResolutionStage() {
private fun FirThisReceiverExpression.getDslMarkersOfThisReceiverExpression(context: ResolutionContext): Set<ClassId> { private fun FirThisReceiverExpression.getDslMarkersOfThisReceiverExpression(context: ResolutionContext): Set<ClassId> {
return buildSet { return buildSet {
collectDslMarkerAnnotations(context, coneType) collectDslMarkerAnnotations(context, resolvedType)
} }
} }
@@ -713,7 +719,7 @@ internal object ProcessDynamicExtensionAnnotation : ResolutionStage() {
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
if (candidate.symbol.origin === FirDeclarationOrigin.DynamicScope) return if (candidate.symbol.origin === FirDeclarationOrigin.DynamicScope) return
val extensionReceiver = candidate.chosenExtensionReceiver ?: return val extensionReceiver = candidate.chosenExtensionReceiver ?: return
val argumentIsDynamic = extensionReceiver.coneType is ConeDynamicType val argumentIsDynamic = extensionReceiver.resolvedType is ConeDynamicType
val parameterIsDynamic = (candidate.symbol as? FirCallableSymbol)?.resolvedReceiverTypeRef?.type is ConeDynamicType val parameterIsDynamic = (candidate.symbol as? FirCallableSymbol)?.resolvedReceiverTypeRef?.type is ConeDynamicType
if (parameterIsDynamic != argumentIsDynamic || if (parameterIsDynamic != argumentIsDynamic ||
parameterIsDynamic && !candidate.symbol.hasAnnotation(DYNAMIC_EXTENSION_ANNOTATION_CLASS_ID, context.session) parameterIsDynamic && !candidate.symbol.hasAnnotation(DYNAMIC_EXTENSION_ANNOTATION_CLASS_ID, context.session)
@@ -21,9 +21,9 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isNullableNothing import org.jetbrains.kotlin.fir.types.isNullableNothing
import org.jetbrains.kotlin.fir.types.makeConeTypeDefinitelyNotNullOrNotNull import org.jetbrains.kotlin.fir.types.makeConeTypeDefinitelyNotNullOrNotNull
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.typeContext import org.jetbrains.kotlin.fir.types.typeContext
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -86,11 +86,11 @@ private fun removeSmartCastTypeForAttemptToFitVisibility(dispatchReceiver: FirEx
val expressionWithSmartcastIfStable = val expressionWithSmartcastIfStable =
(dispatchReceiver as? FirSmartCastExpression)?.takeIf { it.isStable } ?: return null (dispatchReceiver as? FirSmartCastExpression)?.takeIf { it.isStable } ?: return null
val receiverType = dispatchReceiver.coneType val receiverType = dispatchReceiver.resolvedType
if (receiverType.isNullableNothing) return null if (receiverType.isNullableNothing) return null
val originalExpression = expressionWithSmartcastIfStable.originalExpression val originalExpression = expressionWithSmartcastIfStable.originalExpression
val originalType = originalExpression.coneType val originalType = originalExpression.resolvedType
val originalTypeNotNullable = val originalTypeNotNullable =
originalType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext) originalType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext)
@@ -86,7 +86,7 @@ class MemberScopeTowerLevel(
var (empty, candidates) = scope.collectCandidates(processScopeMembers) var (empty, candidates) = scope.collectCandidates(processScopeMembers)
val scopeWithoutSmartcast = getOriginalReceiverExpressionIfStableSmartCast() val scopeWithoutSmartcast = getOriginalReceiverExpressionIfStableSmartCast()
?.coneType ?.resolvedType
?.scope( ?.scope(
session, session,
scopeSession, scopeSession,
@@ -383,7 +383,7 @@ class ScopeTowerLevel(
) )
return givenExtensionReceiverOptions.none { extensionReceiver -> return givenExtensionReceiverOptions.none { extensionReceiver ->
val extensionReceiverType = extensionReceiver.coneType val extensionReceiverType = extensionReceiver.resolvedType
// If some receiver is non class like, we should not skip it // If some receiver is non class like, we should not skip it
if (extensionReceiverType !is ConeClassLikeType) return@none true if (extensionReceiverType !is ConeClassLikeType) return@none true
@@ -404,8 +404,8 @@ abstract class FirDataFlowAnalyzer(
val rightConst = rightOperand as? FirConstExpression<*> val rightConst = rightOperand as? FirConstExpression<*>
val leftIsNullConst = leftConst?.kind == ConstantValueKind.Null val leftIsNullConst = leftConst?.kind == ConstantValueKind.Null
val rightIsNullConst = rightConst?.kind == ConstantValueKind.Null val rightIsNullConst = rightConst?.kind == ConstantValueKind.Null
val leftIsNull = leftIsNullConst || leftOperand.coneType.isNullableNothing && !rightIsNullConst val leftIsNull = leftIsNullConst || leftOperand.resolvedType.isNullableNothing && !rightIsNullConst
val rightIsNull = rightIsNullConst || rightOperand.coneType.isNullableNothing && !leftIsNullConst val rightIsNull = rightIsNullConst || rightOperand.resolvedType.isNullableNothing && !leftIsNullConst
node.mergeIncomingFlow { _, flow -> node.mergeIncomingFlow { _, flow ->
when { when {
@@ -432,10 +432,10 @@ abstract class FirDataFlowAnalyzer(
val operandVariable = variableStorage.getOrCreateIfReal(flow, operand) ?: return val operandVariable = variableStorage.getOrCreateIfReal(flow, operand) ?: return
val expressionVariable = variableStorage.createSynthetic(expression) val expressionVariable = variableStorage.createSynthetic(expression)
if (const.kind == ConstantValueKind.Boolean && operand.coneType.isBooleanOrNullableBoolean) { if (const.kind == ConstantValueKind.Boolean && operand.resolvedType.isBooleanOrNullableBoolean) {
val expected = (const.value as Boolean) val expected = (const.value as Boolean)
flow.addImplication((expressionVariable eq isEq) implies (operandVariable eq expected)) flow.addImplication((expressionVariable eq isEq) implies (operandVariable eq expected))
if (operand.coneType.isBoolean) { if (operand.resolvedType.isBoolean) {
flow.addImplication((expressionVariable eq !isEq) implies (operandVariable eq !expected)) flow.addImplication((expressionVariable eq !isEq) implies (operandVariable eq !expected))
} }
} else { } else {
@@ -459,8 +459,8 @@ abstract class FirDataFlowAnalyzer(
operation: FirOperation, operation: FirOperation,
) { ) {
val isEq = operation.isEq() val isEq = operation.isEq()
val leftOperandType = leftOperand.coneType val leftOperandType = leftOperand.resolvedType
val rightOperandType = rightOperand.coneType val rightOperandType = rightOperand.resolvedType
val leftIsNullable = leftOperandType.isMarkedNullable val leftIsNullable = leftOperandType.isMarkedNullable
val rightIsNullable = rightOperandType.isMarkedNullable val rightIsNullable = rightOperandType.isMarkedNullable
@@ -581,7 +581,7 @@ abstract class FirDataFlowAnalyzer(
private fun CFGNode<*>.mergeWhenBranchEntryFlow() = mergeIncomingFlow { _, flow -> private fun CFGNode<*>.mergeWhenBranchEntryFlow() = mergeIncomingFlow { _, flow ->
val previousConditionExitNode = previousNodes.singleOrNull() as? WhenBranchConditionExitNode ?: return@mergeIncomingFlow val previousConditionExitNode = previousNodes.singleOrNull() as? WhenBranchConditionExitNode ?: return@mergeIncomingFlow
val previousCondition = previousConditionExitNode.fir.condition val previousCondition = previousConditionExitNode.fir.condition
if (!previousCondition.coneType.isBoolean) return@mergeIncomingFlow if (!previousCondition.resolvedType.isBoolean) return@mergeIncomingFlow
val previousConditionVariable = variableStorage.get(flow, previousCondition) ?: return@mergeIncomingFlow val previousConditionVariable = variableStorage.get(flow, previousCondition) ?: return@mergeIncomingFlow
flow.commitOperationStatement(previousConditionVariable eq false) flow.commitOperationStatement(previousConditionVariable eq false)
} }
@@ -591,7 +591,7 @@ abstract class FirDataFlowAnalyzer(
conditionExitNode.mergeIncomingFlow() conditionExitNode.mergeIncomingFlow()
resultEnterNode.mergeIncomingFlow { _, flow -> resultEnterNode.mergeIncomingFlow { _, flow ->
// If the condition is invalid, don't generate smart casts to Any or Boolean. // If the condition is invalid, don't generate smart casts to Any or Boolean.
if (whenBranch.condition.coneType.isBoolean) { if (whenBranch.condition.resolvedType.isBoolean) {
val conditionVariable = variableStorage.get(flow, whenBranch.condition) ?: return@mergeIncomingFlow val conditionVariable = variableStorage.get(flow, whenBranch.condition) ?: return@mergeIncomingFlow
flow.commitOperationStatement(conditionVariable eq true) flow.commitOperationStatement(conditionVariable eq true)
} }
@@ -624,7 +624,7 @@ abstract class FirDataFlowAnalyzer(
val (loopConditionExitNode, loopBlockEnterNode) = graphBuilder.exitWhileLoopCondition(loop) val (loopConditionExitNode, loopBlockEnterNode) = graphBuilder.exitWhileLoopCondition(loop)
loopConditionExitNode.mergeIncomingFlow() loopConditionExitNode.mergeIncomingFlow()
loopBlockEnterNode.mergeIncomingFlow { _, flow -> loopBlockEnterNode.mergeIncomingFlow { _, flow ->
if (loop.condition.coneType.isBoolean) { if (loop.condition.resolvedType.isBoolean) {
val conditionVariable = variableStorage.get(flow, loop.condition) ?: return@mergeIncomingFlow val conditionVariable = variableStorage.get(flow, loop.condition) ?: return@mergeIncomingFlow
flow.commitOperationStatement(conditionVariable eq true) flow.commitOperationStatement(conditionVariable eq true)
} }
@@ -668,7 +668,7 @@ abstract class FirDataFlowAnalyzer(
private fun processLoopExit(flow: MutableFlow, node: LoopExitNode, conditionExitNode: LoopConditionExitNode) { private fun processLoopExit(flow: MutableFlow, node: LoopExitNode, conditionExitNode: LoopConditionExitNode) {
if (conditionExitNode.isDead || node.previousNodes.count { !it.isDead } > 1) return if (conditionExitNode.isDead || node.previousNodes.count { !it.isDead } > 1) return
if (conditionExitNode.fir.coneType.isBoolean) { if (conditionExitNode.fir.resolvedType.isBoolean) {
val variable = variableStorage.get(flow, conditionExitNode.fir) ?: return val variable = variableStorage.get(flow, conditionExitNode.fir) ?: return
flow.commitOperationStatement(variable eq false) flow.commitOperationStatement(variable eq false)
} }
@@ -973,7 +973,7 @@ abstract class FirDataFlowAnalyzer(
if (isAssignment) { if (isAssignment) {
// `propertyVariable` can be an alias to `initializerVariable`, in which case this will add // `propertyVariable` can be an alias to `initializerVariable`, in which case this will add
// a redundant type statement which is fine...probably // a redundant type statement which is fine...probably
flow.addTypeStatement(flow.unwrapVariable(propertyVariable) typeEq initializer.coneType) flow.addTypeStatement(flow.unwrapVariable(propertyVariable) typeEq initializer.resolvedType)
} }
} }
@@ -1014,7 +1014,7 @@ abstract class FirDataFlowAnalyzer(
val flowFromRight = rightOperandNode.getFlow(path) val flowFromRight = rightOperandNode.getFlow(path)
val leftVariable = variableStorage.get(flowFromLeft, fir.leftOperand) val leftVariable = variableStorage.get(flowFromLeft, fir.leftOperand)
val leftIsBoolean = leftVariable != null && fir.leftOperand.coneType.isBoolean val leftIsBoolean = leftVariable != null && fir.leftOperand.resolvedType.isBoolean
if (!leftOperandNode.isDead && rightOperandNode.isDead) { if (!leftOperandNode.isDead && rightOperandNode.isDead) {
// If the right operand does not terminate, then we know that the value of the entire expression // If the right operand does not terminate, then we know that the value of the entire expression
// has to be saturating (true for or, false for and), and it has to be produced by the left operand. // has to be saturating (true for or, false for and), and it has to be produced by the left operand.
@@ -1024,7 +1024,7 @@ abstract class FirDataFlowAnalyzer(
} }
} else { } else {
val rightVariable = variableStorage.get(flowFromRight, fir.rightOperand) val rightVariable = variableStorage.get(flowFromRight, fir.rightOperand)
val rightIsBoolean = rightVariable != null && fir.rightOperand.coneType.isBoolean val rightIsBoolean = rightVariable != null && fir.rightOperand.resolvedType.isBoolean
val operatorVariable = variableStorage.createSynthetic(fir) val operatorVariable = variableStorage.createSynthetic(fir)
// If `left && right` is true, then both are evaluated to true. If `left || right` is false, then both are false. // If `left && right` is true, then both are evaluated to true. If `left || right` is false, then both are false.
// Approved type statements for RHS already contain everything implied by the corresponding value of LHS. // Approved type statements for RHS already contain everything implied by the corresponding value of LHS.
@@ -78,8 +78,8 @@ class FirBuilderInferenceSession(
val dispatchReceiver = dispatchReceiver val dispatchReceiver = dispatchReceiver
return when { return when {
extensionReceiver == null && dispatchReceiver == null -> false extensionReceiver == null && dispatchReceiver == null -> false
dispatchReceiver?.coneType?.containsStubType() == true -> true dispatchReceiver?.resolvedType?.containsStubType() == true -> true
extensionReceiver?.coneType?.containsStubType() == true -> symbol.fir.hasBuilderInferenceAnnotation(session) extensionReceiver?.resolvedType?.containsStubType() == true -> symbol.fir.hasBuilderInferenceAnnotation(session)
else -> false else -> false
} }
} }
@@ -10,7 +10,10 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvable
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstraintPosition import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstraintPosition
import org.jetbrains.kotlin.fir.resolve.substitution.* import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.NotFixedTypeToVariableSubstitutorForDelegateInference
import org.jetbrains.kotlin.fir.resolve.substitution.replaceStubsAndTypeVariablesToErrors
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
@@ -72,8 +75,8 @@ class FirDelegatedPropertyInferenceSession(
if (callee.candidate.system.hasContradiction) return true if (callee.candidate.system.hasContradiction) return true
val hasStubType = val hasStubType =
callee.candidate.chosenExtensionReceiver?.coneType?.containsStubType() ?: false callee.candidate.chosenExtensionReceiver?.resolvedType?.containsStubType() ?: false
|| callee.candidate.dispatchReceiver?.coneType?.containsStubType() ?: false || callee.candidate.dispatchReceiver?.resolvedType?.containsStubType() ?: false
if (!hasStubType) { if (!hasStubType) {
return true return true
@@ -195,7 +195,7 @@ class FirCallCompletionResultsWriterTransformer(
?: return functionCall ?: return functionCall
val result = prepareQualifiedTransform(functionCall, calleeReference) val result = prepareQualifiedTransform(functionCall, calleeReference)
val subCandidate = calleeReference.candidate val subCandidate = calleeReference.candidate
val resultType = result.coneType.substituteType(subCandidate) val resultType = result.resolvedType.substituteType(subCandidate)
if (calleeReference.isError) { if (calleeReference.isError) {
subCandidate.argumentMapping?.let { subCandidate.argumentMapping?.let {
result.replaceArgumentList(buildArgumentListForErrorCall(result.argumentList, it)) result.replaceArgumentList(buildArgumentListForErrorCall(result.argumentList, it))
@@ -352,7 +352,7 @@ class FirCallCompletionResultsWriterTransformer(
val subCandidate = calleeReference.candidate val subCandidate = calleeReference.candidate
val typeArguments = computeTypeArguments(callableReferenceAccess, subCandidate) val typeArguments = computeTypeArguments(callableReferenceAccess, subCandidate)
val initialType = calleeReference.candidate.substitutor.substituteOrSelf(callableReferenceAccess.coneType) val initialType = calleeReference.candidate.substitutor.substituteOrSelf(callableReferenceAccess.resolvedType)
val finalType = finallySubstituteOrSelf(initialType) val finalType = finallySubstituteOrSelf(initialType)
callableReferenceAccess.replaceConeTypeOrNull(finalType) callableReferenceAccess.replaceConeTypeOrNull(finalType)
@@ -394,7 +394,7 @@ class FirCallCompletionResultsWriterTransformer(
qualifiedAccessExpression: FirQualifiedAccessExpression, qualifiedAccessExpression: FirQualifiedAccessExpression,
data: Any? data: Any?
): FirStatement { ): FirStatement {
val originalType = qualifiedAccessExpression.coneType val originalType = qualifiedAccessExpression.resolvedType
val substitutedReceiverType = finallySubstituteOrNull(originalType) ?: return qualifiedAccessExpression val substitutedReceiverType = finallySubstituteOrNull(originalType) ?: return qualifiedAccessExpression
qualifiedAccessExpression.replaceConeTypeOrNull(substitutedReceiverType) qualifiedAccessExpression.replaceConeTypeOrNull(substitutedReceiverType)
session.lookupTracker?.recordTypeResolveAsLookup(substitutedReceiverType, qualifiedAccessExpression.source, context.file.source) session.lookupTracker?.recordTypeResolveAsLookup(substitutedReceiverType, qualifiedAccessExpression.source, context.file.source)
@@ -570,7 +570,7 @@ class FirCallCompletionResultsWriterTransformer(
// Prefer the expected type over the inferred one - the latter is a subtype of the former in valid code, // Prefer the expected type over the inferred one - the latter is a subtype of the former in valid code,
// and there will be ARGUMENT_TYPE_MISMATCH errors on the lambda's return expressions in invalid code. // and there will be ARGUMENT_TYPE_MISMATCH errors on the lambda's return expressions in invalid code.
val resultReturnType = expectedReturnType val resultReturnType = expectedReturnType
?: session.typeContext.commonSuperTypeOrNull(returnExpressions.map { it.coneType }) ?: session.typeContext.commonSuperTypeOrNull(returnExpressions.map { it.resolvedType })
?: session.builtinTypes.unitType.type ?: session.builtinTypes.unitType.type
if (initialReturnType != resultReturnType) { if (initialReturnType != resultReturnType) {
@@ -702,7 +702,7 @@ class FirCallCompletionResultsWriterTransformer(
syntheticCall: D, syntheticCall: D,
data: ExpectedArgumentType? data: ExpectedArgumentType?
) where D : FirResolvable, D : FirExpression { ) where D : FirResolvable, D : FirExpression {
val newData = data?.getExpectedType(syntheticCall)?.toExpectedType() ?: syntheticCall.coneType.toExpectedType() val newData = data?.getExpectedType(syntheticCall)?.toExpectedType() ?: syntheticCall.resolvedType.toExpectedType()
if (syntheticCall is FirTryExpression) { if (syntheticCall is FirTryExpression) {
syntheticCall.transformCalleeReference(this, newData) syntheticCall.transformCalleeReference(this, newData)
@@ -747,7 +747,7 @@ class FirCallCompletionResultsWriterTransformer(
val expectedArrayElementType = expectedArrayType?.arrayElementType() val expectedArrayElementType = expectedArrayType?.arrayElementType()
arrayLiteral.transformChildren(this, expectedArrayElementType?.toExpectedType()) arrayLiteral.transformChildren(this, expectedArrayElementType?.toExpectedType())
val arrayElementType = val arrayElementType =
session.typeContext.commonSuperTypeOrNull(arrayLiteral.arguments.map { it.coneType })?.let { session.typeContext.commonSuperTypeOrNull(arrayLiteral.arguments.map { it.resolvedType })?.let {
typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference) typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference)
?: it ?: it
} ?: expectedArrayElementType ?: session.builtinTypes.nullableAnyType.type } ?: expectedArrayElementType ?: session.builtinTypes.nullableAnyType.type
@@ -54,7 +54,7 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
private fun getSubjectType(session: FirSession, whenExpression: FirWhenExpression): ConeKotlinType? { private fun getSubjectType(session: FirSession, whenExpression: FirWhenExpression): ConeKotlinType? {
val subjectType = whenExpression.subjectVariable?.returnTypeRef?.coneType val subjectType = whenExpression.subjectVariable?.returnTypeRef?.coneType
?: whenExpression.subject?.coneType ?: whenExpression.subject?.resolvedType
?: return null ?: return null
return subjectType.fullyExpandedType(session).lowerBoundIfFlexible() return subjectType.fullyExpandedType(session).lowerBoundIfFlexible()
@@ -64,7 +64,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
return context.withWhenExpression(whenExpression, session) with@{ return context.withWhenExpression(whenExpression, session) with@{
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
var whenExpression = whenExpression.transformSubject(transformer, ResolutionMode.ContextIndependent) var whenExpression = whenExpression.transformSubject(transformer, ResolutionMode.ContextIndependent)
val subjectType = whenExpression.subject?.coneType?.fullyExpandedType(session) val subjectType = whenExpression.subject?.resolvedType?.fullyExpandedType(session)
var completionNeeded = false var completionNeeded = false
context.withWhenSubjectType(subjectType, components) { context.withWhenSubjectType(subjectType, components) {
when { when {
@@ -281,7 +281,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
// Sometimes return type for special call for elvis operator might be nullable, // Sometimes return type for special call for elvis operator might be nullable,
// but result is not nullable if the right type is not nullable // but result is not nullable if the right type is not nullable
result.replaceConeTypeOrNull( result.replaceConeTypeOrNull(
result.coneType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext) result.resolvedType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext)
) )
} }
} }
@@ -343,7 +343,7 @@ open class FirDeclarationsResolveTransformer(
val substitutor = createTypeSubstitutorByTypeConstructor( val substitutor = createTypeSubstitutorByTypeConstructor(
typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true
) )
val delegateExpressionType = delegateExpression.coneType val delegateExpressionType = delegateExpression.resolvedType
val stubTypeSubstituted = substitutor.substituteOrNull(delegateExpressionType) val stubTypeSubstituted = substitutor.substituteOrNull(delegateExpressionType)
delegateExpression.replaceConeTypeOrNull(stubTypeSubstituted) delegateExpression.replaceConeTypeOrNull(stubTypeSubstituted)
} }
@@ -880,7 +880,7 @@ open class FirDeclarationsResolveTransformer(
// In correct code this doesn't matter, as all return expression types should be subtypes of the expected type. // In correct code this doesn't matter, as all return expression types should be subtypes of the expected type.
// In incorrect code, this would change diagnostics: we can get errors either on the entire lambda, or only on its // In incorrect code, this would change diagnostics: we can get errors either on the entire lambda, or only on its
// return statements. The former kind of makes more sense, but the latter is more readable. // return statements. The former kind of makes more sense, but the latter is more readable.
val inferredFromReturnExpressions = session.typeContext.commonSuperTypeOrNull(returnExpressions.map { it.expression.coneType }) val inferredFromReturnExpressions = session.typeContext.commonSuperTypeOrNull(returnExpressions.map { it.expression.resolvedType })
return inferredFromReturnExpressions?.let { returnTypeRef.resolvedTypeFromPrototype(it) } return inferredFromReturnExpressions?.let { returnTypeRef.resolvedTypeFromPrototype(it) }
?: session.builtinTypes.unitType // Empty lambda returns Unit ?: session.builtinTypes.unitType // Empty lambda returns Unit
} }
@@ -604,13 +604,13 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
fun operatorReturnTypeMatches(candidate: Candidate): Boolean { fun operatorReturnTypeMatches(candidate: Candidate): Boolean {
// After KT-45503, non-assign flavor of operator is checked more strictly: the return type must be assignable to the variable. // After KT-45503, non-assign flavor of operator is checked more strictly: the return type must be assignable to the variable.
val operatorCallReturnType = resolvedOperatorCall.coneType val operatorCallReturnType = resolvedOperatorCall.resolvedType
val substitutor = candidate.system.currentStorage() val substitutor = candidate.system.currentStorage()
.buildAbstractResultingSubstitutor(candidate.system.typeSystemContext) as ConeSubstitutor .buildAbstractResultingSubstitutor(candidate.system.typeSystemContext) as ConeSubstitutor
return AbstractTypeChecker.isSubtypeOf( return AbstractTypeChecker.isSubtypeOf(
session.typeContext, session.typeContext,
substitutor.substituteOrSelf(operatorCallReturnType), substitutor.substituteOrSelf(operatorCallReturnType),
leftArgument.coneType leftArgument.resolvedType
) )
} }
// following `!!` is safe since `operatorIsSuccessful = true` implies `operatorCallReference != null` // following `!!` is safe since `operatorIsSuccessful = true` implies `operatorCallReference != null`
@@ -691,7 +691,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
!assignIsSuccessful && !operatorIsSuccessful -> chooseResolved() !assignIsSuccessful && !operatorIsSuccessful -> chooseResolved()
!assignIsSuccessful && operatorIsSuccessful -> chooseOperator() !assignIsSuccessful && operatorIsSuccessful -> chooseOperator()
assignIsSuccessful && !operatorIsSuccessful -> chooseAssign() assignIsSuccessful && !operatorIsSuccessful -> chooseAssign()
leftArgument.coneType is ConeDynamicType -> chooseAssign() leftArgument.resolvedType is ConeDynamicType -> chooseAssign()
!operatorReturnTypeMatches -> chooseAssign() !operatorReturnTypeMatches -> chooseAssign()
else -> reportAmbiguity() else -> reportAmbiguity()
} }
@@ -1117,7 +1117,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
) )
type type
} else { } else {
lhs.coneType lhs.resolvedType
} }
} }
is FirResolvedReifiedParameterReference -> { is FirResolvedReifiedParameterReference -> {
@@ -1189,7 +1189,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
dataFlowAnalyzer.exitConstExpression(constExpression as FirConstExpression<*>) dataFlowAnalyzer.exitConstExpression(constExpression as FirConstExpression<*>)
constExpression.resultType = type constExpression.resultType = type
return when (val resolvedType = constExpression.coneType) { return when (val resolvedType = constExpression.resolvedType) {
is ConeErrorType -> buildErrorExpression { is ConeErrorType -> buildErrorExpression {
expression = constExpression expression = constExpression
diagnostic = resolvedType.diagnostic diagnostic = resolvedType.diagnostic
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.fir.resolve.transformers.contracts package org.jetbrains.kotlin.fir.resolve.transformers.contracts
import org.jetbrains.kotlin.contracts.description.* import org.jetbrains.kotlin.contracts.description.*
import org.jetbrains.kotlin.contracts.description.LogicOperationKind
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.contracts.description.* import org.jetbrains.kotlin.fir.contracts.description.*
@@ -20,6 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.types.toSymbol import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
@@ -194,7 +194,7 @@ class ConeEffectExtractor(
val ownerHasReceiver = callableOwner?.receiverParameter != null val ownerHasReceiver = callableOwner?.receiverParameter != null
val ownerIsMemberOfDeclaration = callableOwner?.getContainingClass(session) == declaration val ownerIsMemberOfDeclaration = callableOwner?.getContainingClass(session) == declaration
return if (declaration == owner || owner.isAccessorOf(declaration) || ownerIsMemberOfDeclaration && !ownerHasReceiver) { return if (declaration == owner || owner.isAccessorOf(declaration) || ownerIsMemberOfDeclaration && !ownerHasReceiver) {
val type = thisReceiverExpression.coneType val type = thisReceiverExpression.resolvedType
toValueParameterReference(type, -1, "this") toValueParameterReference(type, -1, "this")
} else { } else {
ConeContractDescriptionError.IllegalThis(thisReceiverExpression).asElement() ConeContractDescriptionError.IllegalThis(thisReceiverExpression).asElement()
@@ -354,7 +354,7 @@ class FirExpectActualMatchingContextImpl private constructor(
} }
private fun areFirAnnotationsEqual(annotation1: FirAnnotation, annotation2: FirAnnotation): Boolean { private fun areFirAnnotationsEqual(annotation1: FirAnnotation, annotation2: FirAnnotation): Boolean {
if (!areCompatibleExpectActualTypes(annotation1.coneType, annotation2.coneType)) { if (!areCompatibleExpectActualTypes(annotation1.resolvedType, annotation2.resolvedType)) {
return false return false
} }
val args1 = annotation1.argumentMapping.mapping val args1 = annotation1.argumentMapping.mapping
@@ -17,9 +17,9 @@ import org.jetbrains.kotlin.fir.resolve.dfa.PersistentFlow
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.constructClassLikeType import org.jetbrains.kotlin.fir.types.constructClassLikeType
import org.jetbrains.kotlin.fir.types.isNothing import org.jetbrains.kotlin.fir.types.isNothing
import org.jetbrains.kotlin.fir.types.resolvedType
import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
@@ -893,7 +893,7 @@ class FakeExpressionEnterNode(owner: ControlFlowGraph, level: Int) : CFGNode<Fir
class SmartCastExpressionExitNode(owner: ControlFlowGraph, override val fir: FirSmartCastExpression, level: Int) : CFGNode<FirSmartCastExpression>(owner, level) { class SmartCastExpressionExitNode(owner: ControlFlowGraph, override val fir: FirSmartCastExpression, level: Int) : CFGNode<FirSmartCastExpression>(owner, level) {
override val canThrow: Boolean override val canThrow: Boolean
get() = fir.coneType.isNothing get() = fir.resolvedType.isNothing
override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R { override fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R {
return visitor.visitSmartCastExpressionExitNode(this, data) return visitor.visitSmartCastExpressionExitNode(this, data)
@@ -37,7 +37,7 @@ val FirTypeRef.coneType: ConeKotlinType
val FirTypeRef.coneTypeOrNull: ConeKotlinType? val FirTypeRef.coneTypeOrNull: ConeKotlinType?
get() = coneTypeSafe() get() = coneTypeSafe()
val FirExpression.coneType: ConeKotlinType get() = requireNotNull(coneTypeOrNull) { "Expected type to be resolved" } val FirExpression.resolvedType: ConeKotlinType get() = requireNotNull(coneTypeOrNull) { "Expected type to be resolved" }
inline fun <reified T : ConeKotlinType> FirExpression.coneTypeSafe(): T? = (coneTypeOrNull as? T) inline fun <reified T : ConeKotlinType> FirExpression.coneTypeSafe(): T? = (coneTypeOrNull as? T)
@@ -164,7 +164,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
if (function.isLocal) stack.addName(function.name ?: ANONYMOUS_NAME) if (function.isLocal) stack.addName(function.name ?: ANONYMOUS_NAME)
stack.push((function.name ?: ANONYMOUS_NAME)) stack.push((function.name ?: ANONYMOUS_NAME))
if (function.equalsToken != null) { if (function.equalsToken != null) {
function.bodyExpression!!.firstOfTypeWithRender<FirReturnExpression>(function.equalsToken) { this.result.coneType.toFirResolvedTypeRef() } function.bodyExpression!!.firstOfTypeWithRender<FirReturnExpression>(function.equalsToken) { this.result.resolvedType.toFirResolvedTypeRef() }
?: function.firstOfTypeWithRender<FirCallableDeclaration>(function.equalsToken) { this.returnTypeRef } ?: function.firstOfTypeWithRender<FirCallableDeclaration>(function.equalsToken) { this.returnTypeRef }
} }
super.visitNamedFunction(function) super.visitNamedFunction(function)
@@ -249,12 +249,12 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
} }
override fun visitIfExpression(expression: KtIfExpression) { override fun visitIfExpression(expression: KtIfExpression) {
expression.firstOfTypeWithRender<FirWhenExpression> { this.coneType.toFirResolvedTypeRef() } expression.firstOfTypeWithRender<FirWhenExpression> { this.resolvedType.toFirResolvedTypeRef() }
super.visitIfExpression(expression) super.visitIfExpression(expression)
} }
override fun visitWhenExpression(expression: KtWhenExpression) { override fun visitWhenExpression(expression: KtWhenExpression) {
expression.firstOfTypeWithRender<FirWhenExpression> { this.coneType.toFirResolvedTypeRef() } expression.firstOfTypeWithRender<FirWhenExpression> { this.resolvedType.toFirResolvedTypeRef() }
super.visitWhenExpression(expression) super.visitWhenExpression(expression)
} }
@@ -306,7 +306,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
} }
override fun visitWhenEntry(ktWhenEntry: KtWhenEntry) { override fun visitWhenEntry(ktWhenEntry: KtWhenEntry) {
ktWhenEntry.firstOfTypeWithRender<FirWhenBranch>(ktWhenEntry.expression) { this.result.coneType.toFirResolvedTypeRef() } ktWhenEntry.firstOfTypeWithRender<FirWhenBranch>(ktWhenEntry.expression) { this.result.resolvedType.toFirResolvedTypeRef() }
super.visitWhenEntry(ktWhenEntry) super.visitWhenEntry(ktWhenEntry)
} }
@@ -564,7 +564,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
fir.receiverParameter?.accept(this, data) fir.receiverParameter?.accept(this, data)
data.append(".").append(callableName) data.append(".").append(callableName)
} }
call.dispatchReceiver.coneType.isExtensionFunctionType -> { call.dispatchReceiver.resolvedType.isExtensionFunctionType -> {
withExtensionFunctionType = true withExtensionFunctionType = true
fir.valueParameters.first().returnTypeRef.accept(this, data) fir.valueParameters.first().returnTypeRef.accept(this, data)
data.append(".").append(callableName) data.append(".").append(callableName)
@@ -786,7 +786,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: StringBuilder) { override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: StringBuilder) {
when (constExpression.kind) { when (constExpression.kind) {
ConstantValueKind.String -> return ConstantValueKind.String -> return
ConstantValueKind.Null -> constExpression.coneType.tryToRenderConeAsFunctionType(data) ConstantValueKind.Null -> constExpression.resolvedType.tryToRenderConeAsFunctionType(data)
else -> data.append(constExpression.kind) else -> data.append(constExpression.kind)
} }
} }
@@ -796,7 +796,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
when { when {
fir is FirRegularClass && fir.classKind != ClassKind.ENUM_CLASS && fir.companionObjectSymbol?.defaultType() == resolvedQualifier.coneTypeSafe() -> { fir is FirRegularClass && fir.classKind != ClassKind.ENUM_CLASS && fir.companionObjectSymbol?.defaultType() == resolvedQualifier.coneTypeSafe() -> {
data.append("companion object ") data.append("companion object ")
data.append(resolvedQualifier.coneType.toFirResolvedTypeRef().render()).append(": ") data.append(resolvedQualifier.resolvedType.toFirResolvedTypeRef().render()).append(": ")
data.append(fir.symbol.classId.asString().removeCurrentFilePackage()) data.append(fir.symbol.classId.asString().removeCurrentFilePackage())
} }
fir is FirClass -> { fir is FirClass -> {
@@ -845,8 +845,8 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
} }
override fun visitArrayLiteral(arrayLiteral: FirArrayLiteral, data: StringBuilder) { override fun visitArrayLiteral(arrayLiteral: FirArrayLiteral, data: StringBuilder) {
val name = arrayLiteral.coneType.classId!!.shortClassName.asString() val name = arrayLiteral.resolvedType.classId!!.shortClassName.asString()
val typeArguments = arrayLiteral.coneType.typeArguments val typeArguments = arrayLiteral.resolvedType.typeArguments
val typeParameters = if (typeArguments.isEmpty()) "" else " <T>" val typeParameters = if (typeArguments.isEmpty()) "" else " <T>"
data.append("fun$typeParameters ${name.replaceFirstChar(Char::lowercaseChar)}Of") data.append("fun$typeParameters ${name.replaceFirstChar(Char::lowercaseChar)}Of")
typeArguments.firstOrNull()?.let { typeArguments.firstOrNull()?.let {
@@ -5,16 +5,17 @@
package org.jetbrains.kotlin.fir.plugin.checkers package org.jetbrains.kotlin.fir.plugin.checkers
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.InternalDiagnosticFactoryMethod import org.jetbrains.kotlin.diagnostics.InternalDiagnosticFactoryMethod
import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.resolvedArgumentMapping import org.jetbrains.kotlin.fir.expressions.resolvedArgumentMapping
import org.jetbrains.kotlin.fir.plugin.types.ConeNumberSignAttribute import org.jetbrains.kotlin.fir.plugin.types.ConeNumberSignAttribute
import org.jetbrains.kotlin.fir.plugin.types.numberSign import org.jetbrains.kotlin.fir.plugin.types.numberSign
import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.resolvedType
object SignedNumberCallChecker : FirFunctionCallChecker() { object SignedNumberCallChecker : FirFunctionCallChecker() {
@OptIn(InternalDiagnosticFactoryMethod::class) @OptIn(InternalDiagnosticFactoryMethod::class)
@@ -22,7 +23,7 @@ object SignedNumberCallChecker : FirFunctionCallChecker() {
val argumentMapping = expression.resolvedArgumentMapping ?: return val argumentMapping = expression.resolvedArgumentMapping ?: return
for ((argument, parameter) in argumentMapping.entries) { for ((argument, parameter) in argumentMapping.entries) {
val expectedSign = parameter.returnTypeRef.coneType.attributes.numberSign ?: continue val expectedSign = parameter.returnTypeRef.coneType.attributes.numberSign ?: continue
val actualSign = argument.coneType.attributes.numberSign val actualSign = argument.resolvedType.attributes.numberSign
if (expectedSign != actualSign) { if (expectedSign != actualSign) {
reporter.reportOn( reporter.reportOn(
argument.source, PluginErrors.ILLEGAL_NUMBER_SIGN, expectedSign.asString(), actualSign.asString(), context argument.source, PluginErrors.ILLEGAL_NUMBER_SIGN, expectedSign.asString(), actualSign.asString(), context
@@ -175,8 +175,8 @@ object FirSerializationPluginClassChecker : FirClassChecker() {
this is FirConstExpression<*> && other is FirConstExpression<*> -> kind == other.kind && value == other.value this is FirConstExpression<*> && other is FirConstExpression<*> -> kind == other.kind && value == other.value
this is FirGetClassCall && other is FirGetClassCall -> AbstractTypeChecker.equalTypes( this is FirGetClassCall && other is FirGetClassCall -> AbstractTypeChecker.equalTypes(
session.typeContext, session.typeContext,
coneType, resolvedType,
other.coneType other.resolvedType
) )
this is FirPropertyAccessExpression && other is FirPropertyAccessExpression -> this is FirPropertyAccessExpression && other is FirPropertyAccessExpression ->