[FIR] Migrate compiler.fir to use resolvedType where applicable
#KT-61367
This commit is contained in:
committed by
Space Team
parent
1c6776b2b4
commit
66b911c923
@@ -28,11 +28,8 @@ 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.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
|
||||||
import org.jetbrains.kotlin.fir.types.constructType
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.SmartcastStability
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
|
|
||||||
@@ -51,9 +48,7 @@ abstract class ReceiverValue {
|
|||||||
|
|
||||||
class ExpressionReceiverValue(override val receiverExpression: FirExpression) : ReceiverValue() {
|
class ExpressionReceiverValue(override val receiverExpression: FirExpression) : ReceiverValue() {
|
||||||
override val type: ConeKotlinType
|
override val type: ConeKotlinType
|
||||||
// NB: safe cast is necessary here
|
get() = receiverExpression.resolvedType
|
||||||
get() = receiverExpression.coneTypeSafe()
|
|
||||||
?: ConeErrorType(ConeIntermediateDiagnostic("No type calculated for: ${receiverExpression.renderWithType()}")) // TODO: assert here
|
|
||||||
|
|
||||||
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? {
|
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? {
|
||||||
var receiverExpr: FirExpression? = receiverExpression
|
var receiverExpr: FirExpression? = receiverExpression
|
||||||
|
|||||||
@@ -549,7 +549,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
}
|
}
|
||||||
val customAnnotations = attributes.customAnnotations
|
val customAnnotations = attributes.customAnnotations
|
||||||
return customAnnotations.any {
|
return customAnnotations.any {
|
||||||
it.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session)?.classId?.asSingleFqName() == fqName
|
it.resolvedType.fullyExpandedType(session).classId?.asSingleFqName() == fqName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,7 +558,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
// We don't check for compiler attributes because all of them doesn't have parameters
|
// We don't check for compiler attributes because all of them doesn't have parameters
|
||||||
val customAnnotations = attributes.customAnnotations
|
val customAnnotations = attributes.customAnnotations
|
||||||
val annotationCall = customAnnotations.firstOrNull {
|
val annotationCall = customAnnotations.firstOrNull {
|
||||||
it.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session)?.classId?.asSingleFqName() == fqName
|
it.resolvedType.fullyExpandedType(session).classId?.asSingleFqName() == fqName
|
||||||
} ?: return null
|
} ?: return null
|
||||||
val argument = when (val argument = annotationCall.argumentMapping.mapping.values.firstOrNull() ?: return null) {
|
val argument = when (val argument = annotationCall.argumentMapping.mapping.values.firstOrNull() ?: return null) {
|
||||||
is FirVarargArgumentsExpression -> argument.arguments.firstOrNull()
|
is FirVarargArgumentsExpression -> argument.arguments.firstOrNull()
|
||||||
|
|||||||
@@ -826,7 +826,7 @@ class FirCallResolver(
|
|||||||
*/
|
*/
|
||||||
if (components.context.inferenceSession !is FirBuilderInferenceSession &&
|
if (components.context.inferenceSession !is FirBuilderInferenceSession &&
|
||||||
createResolvedReferenceWithoutCandidateForLocalVariables &&
|
createResolvedReferenceWithoutCandidateForLocalVariables &&
|
||||||
explicitReceiver?.coneTypeSafe<ConeIntegerLiteralType>() == null &&
|
explicitReceiver?.resolvedType !is ConeIntegerLiteralType &&
|
||||||
coneSymbol is FirVariableSymbol &&
|
coneSymbol is FirVariableSymbol &&
|
||||||
(coneSymbol !is FirPropertySymbol || (coneSymbol.fir as FirMemberDeclaration).typeParameters.isEmpty()) &&
|
(coneSymbol !is FirPropertySymbol || (coneSymbol.fir as FirMemberDeclaration).typeParameters.isEmpty()) &&
|
||||||
!candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()
|
!candidate.doesResolutionResultOverrideOtherToPreserveCompatibility()
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ fun FirAnonymousFunction.addReturnToLastStatementIfNeeded(session: FirSession) {
|
|||||||
val lastStatement = body.statements.lastOrNull() as? FirExpression ?: return
|
val lastStatement = body.statements.lastOrNull() as? FirExpression ?: return
|
||||||
if (lastStatement is FirReturnExpression) return
|
if (lastStatement is FirReturnExpression) return
|
||||||
|
|
||||||
val returnType = body.coneTypeOrNull ?: return
|
val returnType = body.resolvedType
|
||||||
if (returnType.isNothing) return
|
if (returnType.isNothing) return
|
||||||
|
|
||||||
val returnTarget = FirFunctionTarget(null, isLambda = isLambda).also { it.bind(this) }
|
val returnTarget = FirFunctionTarget(null, isLambda = isLambda).also { it.bind(this) }
|
||||||
@@ -211,7 +211,7 @@ fun BodyResolveComponents.buildResolvedQualifierForClass(
|
|||||||
this.annotations.addAll(annotations)
|
this.annotations.addAll(annotations)
|
||||||
}.build().apply {
|
}.build().apply {
|
||||||
if (classId.isLocal) {
|
if (classId.isLocal) {
|
||||||
resultType = typeForQualifierByDeclaration(regularClass.fir, resultType, session)
|
resultType = typeForQualifierByDeclaration(regularClass.fir, session)
|
||||||
?.also { replaceCanBeValue(true) }
|
?.also { replaceCanBeValue(true) }
|
||||||
?: session.builtinTypes.unitType.type
|
?: session.builtinTypes.unitType.type
|
||||||
} else {
|
} else {
|
||||||
@@ -222,12 +222,11 @@ fun BodyResolveComponents.buildResolvedQualifierForClass(
|
|||||||
|
|
||||||
fun FirResolvedQualifier.setTypeOfQualifier(session: FirSession) {
|
fun FirResolvedQualifier.setTypeOfQualifier(session: FirSession) {
|
||||||
val classSymbol = symbol
|
val classSymbol = symbol
|
||||||
val resultType = resultType
|
|
||||||
if (classSymbol != null) {
|
if (classSymbol != null) {
|
||||||
classSymbol.lazyResolveToPhase(FirResolvePhase.TYPES)
|
classSymbol.lazyResolveToPhase(FirResolvePhase.TYPES)
|
||||||
val declaration = classSymbol.fir
|
val declaration = classSymbol.fir
|
||||||
if (declaration !is FirTypeAlias || typeArguments.isEmpty()) {
|
if (declaration !is FirTypeAlias || typeArguments.isEmpty()) {
|
||||||
val typeByDeclaration = typeForQualifierByDeclaration(declaration, resultType, session)
|
val typeByDeclaration = typeForQualifierByDeclaration(declaration, session)
|
||||||
if (typeByDeclaration != null) {
|
if (typeByDeclaration != null) {
|
||||||
this.resultType = typeByDeclaration
|
this.resultType = typeByDeclaration
|
||||||
replaceCanBeValue(true)
|
replaceCanBeValue(true)
|
||||||
@@ -243,10 +242,10 @@ internal fun typeForReifiedParameterReference(parameterReferenceBuilder: FirReso
|
|||||||
return typeParameterSymbol.constructType(emptyArray(), false)
|
return typeParameterSymbol.constructType(emptyArray(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun typeForQualifierByDeclaration(declaration: FirDeclaration, resultType: ConeKotlinType?, session: FirSession): ConeKotlinType? {
|
internal fun typeForQualifierByDeclaration(declaration: FirDeclaration, session: FirSession): ConeKotlinType? {
|
||||||
if (declaration is FirTypeAlias) {
|
if (declaration is FirTypeAlias) {
|
||||||
val expandedDeclaration = declaration.expandedConeType?.lookupTag?.toSymbol(session)?.fir ?: return null
|
val expandedDeclaration = declaration.expandedConeType?.lookupTag?.toSymbol(session)?.fir ?: return null
|
||||||
return typeForQualifierByDeclaration(expandedDeclaration, resultType, session)
|
return typeForQualifierByDeclaration(expandedDeclaration, session)
|
||||||
}
|
}
|
||||||
if (declaration is FirRegularClass) {
|
if (declaration is FirRegularClass) {
|
||||||
if (declaration.classKind == ClassKind.OBJECT) {
|
if (declaration.classKind == ClassKind.OBJECT) {
|
||||||
@@ -398,7 +397,7 @@ private fun FirSmartCastExpressionBuilder.applyResultTypeRef() {
|
|||||||
if (smartcastStability == SmartcastStability.STABLE_VALUE)
|
if (smartcastStability == SmartcastStability.STABLE_VALUE)
|
||||||
smartcastType.coneTypeOrNull
|
smartcastType.coneTypeOrNull
|
||||||
else
|
else
|
||||||
originalExpression.coneTypeOrNull
|
originalExpression.resolvedType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : FirExpression> BodyResolveComponents.transformExpressionUsingSmartcastInfo(
|
private fun <T : FirExpression> BodyResolveComponents.transformExpressionUsingSmartcastInfo(
|
||||||
@@ -473,8 +472,7 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver(
|
|||||||
?.takeIf { it.isStable }
|
?.takeIf { it.isStable }
|
||||||
?.smartcastTypeWithoutNullableNothing
|
?.smartcastTypeWithoutNullableNothing
|
||||||
?.coneTypeSafe<ConeKotlinType>()
|
?.coneTypeSafe<ConeKotlinType>()
|
||||||
?: nullableReceiverExpression.coneTypeOrNull
|
?: nullableReceiverExpression.resolvedType
|
||||||
?: return
|
|
||||||
|
|
||||||
val expandedReceiverType = receiverType.fullyExpandedType(session)
|
val expandedReceiverType = receiverType.fullyExpandedType(session)
|
||||||
val updatedReceiverType = expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext).independentInstance()
|
val updatedReceiverType = expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext).independentInstance()
|
||||||
@@ -490,7 +488,7 @@ fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck(
|
|||||||
|
|
||||||
val resultingType = when {
|
val resultingType = when {
|
||||||
selector is FirExpression && !selector.isStatementLikeExpression -> {
|
selector is FirExpression && !selector.isStatementLikeExpression -> {
|
||||||
val type = selector.coneTypeSafe<ConeKotlinType>() ?: return
|
val type = selector.resolvedType
|
||||||
type.withNullability(ConeNullability.NULLABLE, session.typeContext)
|
type.withNullability(ConeNullability.NULLABLE, session.typeContext)
|
||||||
}
|
}
|
||||||
// Branch for things that shouldn't be used as expressions.
|
// Branch for things that shouldn't be used as expressions.
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ fun Candidate.resolvePlainExpressionArgument(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
if (expectedType == null) return
|
if (expectedType == null) return
|
||||||
val argumentType = argument.coneTypeSafe<ConeKotlinType>() ?: return
|
val argumentType = argument.resolvedType
|
||||||
resolvePlainArgumentType(
|
resolvePlainArgumentType(
|
||||||
csBuilder,
|
csBuilder,
|
||||||
argument,
|
argument,
|
||||||
@@ -434,7 +434,9 @@ internal fun Candidate.resolveArgument(
|
|||||||
sink: CheckerSink,
|
sink: CheckerSink,
|
||||||
context: ResolutionContext
|
context: ResolutionContext
|
||||||
) {
|
) {
|
||||||
argument.resultType.ensureResolvedTypeDeclaration(context.session)
|
// Lambdas and callable references can be unresolved at this point
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
|
argument.coneTypeOrNull.ensureResolvedTypeDeclaration(context.session)
|
||||||
val expectedType =
|
val expectedType =
|
||||||
prepareExpectedType(context.session, context.bodyResolveComponents.scopeSession, callInfo, argument, parameter, context)
|
prepareExpectedType(context.session, context.bodyResolveComponents.scopeSession, callInfo, argument, parameter, context)
|
||||||
resolveArgumentExpression(
|
resolveArgumentExpression(
|
||||||
@@ -533,7 +535,7 @@ fun FirExpression.isFunctional(
|
|||||||
is FirAnonymousFunctionExpression, is FirCallableReferenceAccess -> return true
|
is FirAnonymousFunctionExpression, is FirCallableReferenceAccess -> return true
|
||||||
else -> {
|
else -> {
|
||||||
// Either a functional type or a subtype of a class that has a contributed `invoke`.
|
// Either a functional type or a subtype of a class that has a contributed `invoke`.
|
||||||
val coneType = coneTypeSafe<ConeKotlinType>() ?: return false
|
val coneType = resolvedType
|
||||||
if (coneType.isSomeFunctionType(session)) {
|
if (coneType.isSomeFunctionType(session)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -12,10 +12,7 @@ import org.jetbrains.kotlin.builtins.functions.isBasicFunctionOrKFunction
|
|||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildNamedArgumentExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedCallableReferenceTarget
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnsupportedCallableReferenceTarget
|
||||||
@@ -409,6 +406,7 @@ class FirFakeArgumentForCallableReference(
|
|||||||
override val source: KtSourceElement?
|
override val source: KtSourceElement?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
|
@UnresolvedExpressionTypeAccess
|
||||||
override val coneTypeOrNull: ConeKotlinType
|
override val coneTypeOrNull: ConeKotlinType
|
||||||
get() = shouldNotBeCalled()
|
get() = shouldNotBeCalled()
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() {
|
|||||||
when (receiverKind) {
|
when (receiverKind) {
|
||||||
NO_EXPLICIT_RECEIVER -> {
|
NO_EXPLICIT_RECEIVER -> {
|
||||||
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier && !explicitReceiver.isSuperReferenceExpression()) {
|
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier && !explicitReceiver.isSuperReferenceExpression()) {
|
||||||
return sink.yieldDiagnostic(InapplicableWrongReceiver(actualType = explicitReceiver.coneTypeSafe()))
|
return sink.yieldDiagnostic(InapplicableWrongReceiver(actualType = explicitReceiver.resolvedType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
|
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
|
||||||
@@ -742,7 +742,7 @@ internal object LowerPriorityIfDynamic : ResolutionStage() {
|
|||||||
when {
|
when {
|
||||||
candidate.symbol.origin is FirDeclarationOrigin.DynamicScope ->
|
candidate.symbol.origin is FirDeclarationOrigin.DynamicScope ->
|
||||||
candidate.addDiagnostic(LowerPriorityForDynamic)
|
candidate.addDiagnostic(LowerPriorityForDynamic)
|
||||||
candidate.callInfo.isImplicitInvoke && candidate.callInfo.explicitReceiver?.coneTypeSafe<ConeDynamicType>() != null ->
|
candidate.callInfo.isImplicitInvoke && candidate.callInfo.explicitReceiver?.resolvedType is ConeDynamicType ->
|
||||||
candidate.addDiagnostic(LowerPriorityForDynamic)
|
candidate.addDiagnostic(LowerPriorityForDynamic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-4
@@ -923,7 +923,7 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun exitConstExpression(constExpression: FirConstExpression<*>) {
|
fun exitConstExpression(constExpression: FirConstExpression<*>) {
|
||||||
if (constExpression.coneTypeOrNull != null) return
|
if (constExpression.isResolved) return
|
||||||
graphBuilder.exitConstExpression(constExpression).mergeIncomingFlow()
|
graphBuilder.exitConstExpression(constExpression).mergeIncomingFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1135,7 +1135,6 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnexpandedTypeCheck::class)
|
|
||||||
fun exitElvis(elvisExpression: FirElvisExpression, isLhsNotNull: Boolean, callCompleted: Boolean) {
|
fun exitElvis(elvisExpression: FirElvisExpression, isLhsNotNull: Boolean, callCompleted: Boolean) {
|
||||||
val node = graphBuilder.exitElvis(isLhsNotNull, callCompleted)
|
val node = graphBuilder.exitElvis(isLhsNotNull, callCompleted)
|
||||||
node.mergeIncomingFlow { path, flow ->
|
node.mergeIncomingFlow { path, flow ->
|
||||||
@@ -1146,7 +1145,8 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
val elvisVariable by lazy { variableStorage.createSynthetic(elvisExpression) }
|
val elvisVariable by lazy { variableStorage.createSynthetic(elvisExpression) }
|
||||||
|
|
||||||
// If (x ?: null) != null then x != null
|
// If (x ?: null) != null then x != null
|
||||||
if (elvisExpression.rhs.resultType?.isNullableNothing == true) {
|
@OptIn(UnresolvedExpressionTypeAccess::class) // Lambdas can have unresolved type here, see KT-61837
|
||||||
|
if (elvisExpression.rhs.coneTypeOrNull?.isNullableNothing == true) {
|
||||||
val lhsVariable = variableStorage.getOrCreateIfReal(flow, elvisExpression.lhs)
|
val lhsVariable = variableStorage.getOrCreateIfReal(flow, elvisExpression.lhs)
|
||||||
if (lhsVariable != null) {
|
if (lhsVariable != null) {
|
||||||
flow.addImplication((elvisVariable notEq null) implies (lhsVariable notEq null))
|
flow.addImplication((elvisVariable notEq null) implies (lhsVariable notEq null))
|
||||||
@@ -1154,7 +1154,8 @@ abstract class FirDataFlowAnalyzer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If (null ?: x) != null then x != null
|
// If (null ?: x) != null then x != null
|
||||||
if (elvisExpression.lhs.resultType?.isNullableNothing == true) {
|
@OptIn(UnresolvedExpressionTypeAccess::class) // Lambdas can have unresolved type here, see KT-61837
|
||||||
|
if (elvisExpression.lhs.coneTypeOrNull?.isNullableNothing == true) {
|
||||||
val rhsVariable = variableStorage.getOrCreateIfReal(flow, elvisExpression.rhs)
|
val rhsVariable = variableStorage.getOrCreateIfReal(flow, elvisExpression.rhs)
|
||||||
if (rhsVariable != null) {
|
if (rhsVariable != null) {
|
||||||
flow.addImplication((elvisVariable notEq null) implies (rhsVariable notEq null))
|
flow.addImplication((elvisVariable notEq null) implies (rhsVariable notEq null))
|
||||||
|
|||||||
+13
-7
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildUnitExpression
|
|||||||
import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.*
|
import org.jetbrains.kotlin.fir.resolve.dfa.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -1115,7 +1114,7 @@ class ControlFlowGraphBuilder {
|
|||||||
// KT-59726
|
// KT-59726
|
||||||
// @returns `true` if node actually returned Nothing
|
// @returns `true` if node actually returned Nothing
|
||||||
private fun completeFunctionCall(node: FunctionCallNode): Boolean {
|
private fun completeFunctionCall(node: FunctionCallNode): Boolean {
|
||||||
if (node.fir.resultType?.isNothing != true) return false
|
if (!node.fir.hasNothingType) return false
|
||||||
val stub = StubNode(node.owner, node.level)
|
val stub = StubNode(node.owner, node.level)
|
||||||
val edges = node.followingNodes.map { it to node.edgeTo(it) }
|
val edges = node.followingNodes.map { it to node.edgeTo(it) }
|
||||||
CFGNode.removeAllOutgoingEdges(node)
|
CFGNode.removeAllOutgoingEdges(node)
|
||||||
@@ -1132,7 +1131,7 @@ class ControlFlowGraphBuilder {
|
|||||||
// ----------------------------------- Resolvable call -----------------------------------
|
// ----------------------------------- Resolvable call -----------------------------------
|
||||||
|
|
||||||
fun exitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression): QualifiedAccessNode {
|
fun exitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression): QualifiedAccessNode {
|
||||||
val returnsNothing = qualifiedAccessExpression.resultType?.isNothing == true
|
val returnsNothing = qualifiedAccessExpression.hasNothingType
|
||||||
val node = createQualifiedAccessNode(qualifiedAccessExpression)
|
val node = createQualifiedAccessNode(qualifiedAccessExpression)
|
||||||
if (returnsNothing) {
|
if (returnsNothing) {
|
||||||
addNonSuccessfullyTerminatingNode(node)
|
addNonSuccessfullyTerminatingNode(node)
|
||||||
@@ -1143,7 +1142,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun exitSmartCastExpression(smartCastExpression: FirSmartCastExpression): SmartCastExpressionExitNode {
|
fun exitSmartCastExpression(smartCastExpression: FirSmartCastExpression): SmartCastExpressionExitNode {
|
||||||
val returnsNothing = smartCastExpression.resultType?.isNothing == true
|
val returnsNothing = smartCastExpression.hasNothingType
|
||||||
val node = createSmartCastExitNode(smartCastExpression)
|
val node = createSmartCastExitNode(smartCastExpression)
|
||||||
if (returnsNothing) {
|
if (returnsNothing) {
|
||||||
addNonSuccessfullyTerminatingNode(node)
|
addNonSuccessfullyTerminatingNode(node)
|
||||||
@@ -1176,7 +1175,7 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun exitFunctionCall(functionCall: FirFunctionCall, callCompleted: Boolean): FunctionCallNode {
|
fun exitFunctionCall(functionCall: FirFunctionCall, callCompleted: Boolean): FunctionCallNode {
|
||||||
val returnsNothing = functionCall.resultType?.isNothing == true
|
val returnsNothing = functionCall.hasNothingType
|
||||||
val node = createFunctionCallNode(functionCall)
|
val node = createFunctionCallNode(functionCall)
|
||||||
unifyDataFlowFromPostponedLambdas(node, callCompleted)
|
unifyDataFlowFromPostponedLambdas(node, callCompleted)
|
||||||
if (returnsNothing) {
|
if (returnsNothing) {
|
||||||
@@ -1241,7 +1240,7 @@ class ControlFlowGraphBuilder {
|
|||||||
fun exitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, callCompleted: Boolean): CheckNotNullCallNode {
|
fun exitCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, callCompleted: Boolean): CheckNotNullCallNode {
|
||||||
val node = createCheckNotNullCallNode(checkNotNullCall)
|
val node = createCheckNotNullCallNode(checkNotNullCall)
|
||||||
unifyDataFlowFromPostponedLambdas(node, callCompleted)
|
unifyDataFlowFromPostponedLambdas(node, callCompleted)
|
||||||
if (checkNotNullCall.resultType?.isNothing == true) {
|
if (checkNotNullCall.hasNothingType) {
|
||||||
addNonSuccessfullyTerminatingNode(node)
|
addNonSuccessfullyTerminatingNode(node)
|
||||||
} else {
|
} else {
|
||||||
addNewSimpleNode(node)
|
addNewSimpleNode(node)
|
||||||
@@ -1348,7 +1347,9 @@ class ControlFlowGraphBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val lhsIsNotNullNode = createElvisLhsIsNotNullNode(elvisExpression).also {
|
val lhsIsNotNullNode = createElvisLhsIsNotNullNode(elvisExpression).also {
|
||||||
val lhsIsNull = elvisExpression.lhs.coneTypeSafe<ConeKotlinType>()?.isNullableNothing == true
|
// TODO Refactor annotation arguments phase to not build CFG so that we can use resolvedType instead, see KT-61834
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
|
val lhsIsNull = elvisExpression.lhs.coneTypeOrNull?.isNullableNothing == true
|
||||||
addEdge(lhsExitNode, it, isDead = lhsIsNull)
|
addEdge(lhsExitNode, it, isDead = lhsIsNull)
|
||||||
addEdge(it, exitNode, propagateDeadness = false)
|
addEdge(it, exitNode, propagateDeadness = false)
|
||||||
}
|
}
|
||||||
@@ -1465,3 +1466,8 @@ val FirControlFlowGraphOwner.isUsedInControlFlowGraphBuilderForFile: Boolean
|
|||||||
is FirProperty -> memberShouldHaveGraph
|
is FirProperty -> memberShouldHaveGraph
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Refactor annotation arguments phase to not build CFG so that we can use resolvedType instead, see KT-61834
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
|
private val FirExpression.hasNothingType: Boolean
|
||||||
|
get() = coneTypeOrNull?.isNothing == true
|
||||||
|
|||||||
+3
-1
@@ -263,6 +263,8 @@ class FirStubTypeTransformer(private val substitutor: ConeSubstitutor) : FirDefa
|
|||||||
// FirAnonymousFunctionExpression doesn't support replacing the type
|
// FirAnonymousFunctionExpression doesn't support replacing the type
|
||||||
// since it delegates the getter to the underlying FirAnonymousFunction.
|
// since it delegates the getter to the underlying FirAnonymousFunction.
|
||||||
if (element is FirExpression && element !is FirAnonymousFunctionExpression) {
|
if (element is FirExpression && element !is FirAnonymousFunctionExpression) {
|
||||||
|
// TODO Check why some expressions have unresolved type in builder inference session KT-61835
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
element.coneTypeOrNull
|
element.coneTypeOrNull
|
||||||
?.let(substitutor::substituteOrNull)
|
?.let(substitutor::substituteOrNull)
|
||||||
?.let { element.replaceConeTypeOrNull(it) }
|
?.let { element.replaceConeTypeOrNull(it) }
|
||||||
@@ -273,7 +275,7 @@ class FirStubTypeTransformer(private val substitutor: ConeSubstitutor) : FirDefa
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Nothing?): FirStatement {
|
override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Nothing?): FirStatement {
|
||||||
if (typeOperatorCall.argument.coneTypeOrNull is ConeStubType) {
|
if (typeOperatorCall.argument.resolvedType is ConeStubType) {
|
||||||
typeOperatorCall.replaceArgFromStubType(true)
|
typeOperatorCall.replaceArgFromStubType(true)
|
||||||
}
|
}
|
||||||
return super.transformTypeOperatorCall(typeOperatorCall, data)
|
return super.transformTypeOperatorCall(typeOperatorCall, data)
|
||||||
|
|||||||
+10
-12
@@ -265,7 +265,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
val result = prepareQualifiedTransform(qualifiedAccessExpression, calleeReference)
|
val result = prepareQualifiedTransform(qualifiedAccessExpression, calleeReference)
|
||||||
val subCandidate = calleeReference.candidate
|
val subCandidate = calleeReference.candidate
|
||||||
|
|
||||||
val resultType = result.coneTypeOrNull?.substituteType(subCandidate)
|
val resultType = result.resolvedType.substituteType(subCandidate)
|
||||||
resultType.ensureResolvedTypeDeclaration(session)
|
resultType.ensureResolvedTypeDeclaration(session)
|
||||||
result.replaceConeTypeOrNull(resultType)
|
result.replaceConeTypeOrNull(resultType)
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, context.file.source)
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, qualifiedAccessExpression.source, context.file.source)
|
||||||
@@ -726,18 +726,16 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformBlock(block: FirBlock, data: ExpectedArgumentType?): FirStatement {
|
override fun transformBlock(block: FirBlock, data: ExpectedArgumentType?): FirStatement {
|
||||||
val initialType = block.coneTypeSafe<ConeKotlinType>()
|
val initialType = block.resolvedType
|
||||||
if (initialType != null) {
|
var resultType = finallySubstituteOrNull(initialType) ?: block.resolvedType
|
||||||
var resultType = finallySubstituteOrNull(initialType) ?: block.resultType
|
(resultType as? ConeIntegerLiteralType)?.let {
|
||||||
(resultType as? ConeIntegerLiteralType)?.let {
|
resultType =
|
||||||
resultType =
|
it.getApproximatedType(data?.getExpectedType(block)?.fullyExpandedType(session))
|
||||||
it.getApproximatedType(data?.getExpectedType(block)?.fullyExpandedType(session))
|
|
||||||
}
|
|
||||||
block.replaceConeTypeOrNull(resultType)
|
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, context.file.source)
|
|
||||||
}
|
}
|
||||||
|
block.replaceConeTypeOrNull(resultType)
|
||||||
|
session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, context.file.source)
|
||||||
transformElement(block, data)
|
transformElement(block, data)
|
||||||
if (block.resultType is ConeErrorType) {
|
if (block.resolvedType is ConeErrorType) {
|
||||||
block.writeResultType(session)
|
block.writeResultType(session)
|
||||||
}
|
}
|
||||||
return block
|
return block
|
||||||
@@ -838,7 +836,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformArrayLiteral(arrayLiteral: FirArrayLiteral, data: ExpectedArgumentType?): FirStatement {
|
override fun transformArrayLiteral(arrayLiteral: FirArrayLiteral, data: ExpectedArgumentType?): FirStatement {
|
||||||
if (arrayLiteral.coneTypeOrNull != null) return arrayLiteral
|
if (arrayLiteral.isResolved) return arrayLiteral
|
||||||
val expectedArrayType = data?.getExpectedType(arrayLiteral)
|
val expectedArrayType = data?.getExpectedType(arrayLiteral)
|
||||||
val expectedArrayElementType = expectedArrayType?.arrayElementType()
|
val expectedArrayElementType = expectedArrayType?.arrayElementType()
|
||||||
arrayLiteral.transformChildren(this, expectedArrayElementType?.toExpectedType())
|
arrayLiteral.transformChildren(this, expectedArrayElementType?.toExpectedType())
|
||||||
|
|||||||
+1
-1
@@ -242,7 +242,7 @@ class FirSyntheticCallGenerator(
|
|||||||
// If the callable reference cannot be resolved with the expected type, let's try to resolve it with any type and report
|
// If the callable reference cannot be resolved with the expected type, let's try to resolve it with any type and report
|
||||||
// something like INITIALIZER_TYPE_MISMATCH or NONE_APPLICABLE instead of UNRESOLVED_REFERENCE.
|
// something like INITIALIZER_TYPE_MISMATCH or NONE_APPLICABLE instead of UNRESOLVED_REFERENCE.
|
||||||
|
|
||||||
check(callableReferenceAccess.calleeReference is FirSimpleNamedReference && callableReferenceAccess.coneTypeOrNull == null) {
|
check(callableReferenceAccess.calleeReference is FirSimpleNamedReference && !callableReferenceAccess.isResolved) {
|
||||||
"Expected FirCallableReferenceAccess to be unresolved."
|
"Expected FirCallableReferenceAccess to be unresolved."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -223,7 +223,7 @@ private object WhenOnNullableExhaustivenessChecker : WhenExhaustivenessChecker()
|
|||||||
private object ConditionChecker : AbstractConditionChecker<Flags>() {
|
private object ConditionChecker : AbstractConditionChecker<Flags>() {
|
||||||
override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Flags) {
|
override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Flags) {
|
||||||
val argument = equalityOperatorCall.arguments[1]
|
val argument = equalityOperatorCall.arguments[1]
|
||||||
if (argument.coneTypeOrNull?.isNullableNothing == true) {
|
if (argument.resolvedType.isNullableNothing) {
|
||||||
data.containsNull = true
|
data.containsNull = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
|
import org.jetbrains.kotlin.fir.expressions.FirIntegerLiteralOperatorCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||||
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
|
||||||
@@ -59,8 +60,9 @@ class IntegerLiteralAndOperatorApproximationTransformer(
|
|||||||
|
|
||||||
override fun <T> transformConstExpression(
|
override fun <T> transformConstExpression(
|
||||||
constExpression: FirConstExpression<T>,
|
constExpression: FirConstExpression<T>,
|
||||||
data: ConeKotlinType?
|
data: ConeKotlinType?,
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
val type = constExpression.coneTypeSafe<ConeIntegerLiteralType>() ?: return constExpression
|
val type = constExpression.coneTypeSafe<ConeIntegerLiteralType>() ?: return constExpression
|
||||||
val approximatedType = type.getApproximatedType(data?.fullyExpandedType(session))
|
val approximatedType = type.getApproximatedType(data?.fullyExpandedType(session))
|
||||||
constExpression.resultType = approximatedType
|
constExpression.resultType = approximatedType
|
||||||
@@ -72,10 +74,12 @@ class IntegerLiteralAndOperatorApproximationTransformer(
|
|||||||
|
|
||||||
override fun transformIntegerLiteralOperatorCall(
|
override fun transformIntegerLiteralOperatorCall(
|
||||||
integerLiteralOperatorCall: FirIntegerLiteralOperatorCall,
|
integerLiteralOperatorCall: FirIntegerLiteralOperatorCall,
|
||||||
data: ConeKotlinType?
|
data: ConeKotlinType?,
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
@Suppress("UnnecessaryVariable")
|
@Suppress("UnnecessaryVariable")
|
||||||
val call = integerLiteralOperatorCall
|
val call = integerLiteralOperatorCall
|
||||||
|
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
val operatorType = call.coneTypeSafe<ConeIntegerLiteralType>() ?: return call
|
val operatorType = call.coneTypeSafe<ConeIntegerLiteralType>() ?: return call
|
||||||
val approximatedType = operatorType.getApproximatedType(data?.fullyExpandedType(session))
|
val approximatedType = operatorType.getApproximatedType(data?.fullyExpandedType(session))
|
||||||
call.transformDispatchReceiver(this, null)
|
call.transformDispatchReceiver(this, null)
|
||||||
|
|||||||
+8
-7
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -22,8 +23,9 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
|
|
||||||
internal inline var FirExpression.resultType: ConeKotlinType?
|
|
||||||
get() = coneTypeOrNull
|
internal inline var FirExpression.resultType: ConeKotlinType
|
||||||
|
get() = resolvedType
|
||||||
set(type) {
|
set(type) {
|
||||||
replaceConeTypeOrNull(type)
|
replaceConeTypeOrNull(type)
|
||||||
}
|
}
|
||||||
@@ -87,11 +89,10 @@ fun FirBlock.writeResultType(session: FirSession) {
|
|||||||
is FirExpression -> statement
|
is FirExpression -> statement
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
resultType = if (resultExpression == null) {
|
|
||||||
session.builtinTypes.unitType.type
|
// If a lambda contains another lambda as result expression, it won't be resolved at this point
|
||||||
} else {
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
resultExpression.resultType ?: ConeErrorType(ConeSimpleDiagnostic("No type for block", DiagnosticKind.InferenceError))
|
resultType = resultExpression?.coneTypeOrNull ?: session.builtinTypes.unitType.type
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConstantValueKind<*>.expectedConeType(session: FirSession): ConeKotlinType {
|
fun ConstantValueKind<*>.expectedConeType(session: FirSession): ConeKotlinType {
|
||||||
|
|||||||
+2
-1
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.fir.types.isArrayType
|
import org.jetbrains.kotlin.fir.types.isArrayType
|
||||||
|
import org.jetbrains.kotlin.fir.types.resolvedType
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +46,7 @@ class FirArrayOfCallTransformer : FirDefaultTransformer<FirSession>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
coneTypeOrNull = functionCall.coneTypeOrNull
|
coneTypeOrNull = functionCall.resolvedType
|
||||||
}
|
}
|
||||||
|
|
||||||
val calleeReference = functionCall.calleeReference
|
val calleeReference = functionCall.calleeReference
|
||||||
|
|||||||
+16
-17
@@ -56,7 +56,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
|
|||||||
// ------------------------------- When expressions -------------------------------
|
// ------------------------------- When expressions -------------------------------
|
||||||
|
|
||||||
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ResolutionMode): FirStatement {
|
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ResolutionMode): FirStatement {
|
||||||
if (whenExpression.calleeReference is FirResolvedNamedReference && whenExpression.resultType != null) {
|
if (whenExpression.calleeReference is FirResolvedNamedReference && whenExpression.isResolved) {
|
||||||
return whenExpression
|
return whenExpression
|
||||||
}
|
}
|
||||||
whenExpression.annotations.forEach { it.accept(this, data) }
|
whenExpression.annotations.forEach { it.accept(this, data) }
|
||||||
@@ -71,7 +71,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
|
|||||||
whenExpression.branches.isEmpty() -> {}
|
whenExpression.branches.isEmpty() -> {}
|
||||||
whenExpression.isOneBranch() && data.forceFullCompletion && data !is ResolutionMode.WithExpectedType -> {
|
whenExpression.isOneBranch() && data.forceFullCompletion && data !is ResolutionMode.WithExpectedType -> {
|
||||||
whenExpression = whenExpression.transformBranches(transformer, ResolutionMode.ContextIndependent)
|
whenExpression = whenExpression.transformBranches(transformer, ResolutionMode.ContextIndependent)
|
||||||
whenExpression.resultType = whenExpression.branches.first().result.resultType
|
whenExpression.resultType = whenExpression.branches.first().result.resolvedType
|
||||||
// when with one branch cannot be completed if it's not already complete in the first place
|
// when with one branch cannot be completed if it's not already complete in the first place
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -143,7 +143,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
|
|||||||
data: ResolutionMode
|
data: ResolutionMode
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
val parentWhen = whenSubjectExpression.whenRef.value
|
val parentWhen = whenSubjectExpression.whenRef.value
|
||||||
val subjectType = parentWhen.subject?.resultType ?: parentWhen.subjectVariable?.returnTypeRef?.coneTypeOrNull
|
val subjectType = parentWhen.subject?.resolvedType ?: parentWhen.subjectVariable?.returnTypeRef?.coneTypeOrNull
|
||||||
if (subjectType != null) {
|
if (subjectType != null) {
|
||||||
whenSubjectExpression.resultType = subjectType
|
whenSubjectExpression.resultType = subjectType
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
|
|||||||
// ------------------------------- Try/catch expressions -------------------------------
|
// ------------------------------- Try/catch expressions -------------------------------
|
||||||
|
|
||||||
override fun transformTryExpression(tryExpression: FirTryExpression, data: ResolutionMode): FirStatement {
|
override fun transformTryExpression(tryExpression: FirTryExpression, data: ResolutionMode): FirStatement {
|
||||||
if (tryExpression.calleeReference is FirResolvedNamedReference && tryExpression.resultType != null) {
|
if (tryExpression.calleeReference is FirResolvedNamedReference && tryExpression.isResolved) {
|
||||||
return tryExpression
|
return tryExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,22 +262,21 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
|
|||||||
)
|
)
|
||||||
|
|
||||||
var isLhsNotNull = false
|
var isLhsNotNull = false
|
||||||
if (result.rhs.coneTypeSafe<ConeKotlinType>()?.isNothing == true) {
|
|
||||||
val lhsType = result.lhs.coneTypeSafe<ConeKotlinType>()
|
// TODO Check if the type of the RHS being null can lead to a bug, see KT-61837
|
||||||
if (lhsType != null) {
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
// Converting to non-raw type is necessary to preserver the K1 semantics (see KT-54526)
|
if (result.rhs.coneTypeOrNull?.isNothing == true) {
|
||||||
val newReturnType =
|
val lhsType = result.lhs.resolvedType
|
||||||
lhsType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext)
|
// Converting to non-raw type is necessary to preserver the K1 semantics (see KT-54526)
|
||||||
.convertToNonRawVersion()
|
val newReturnType =
|
||||||
result.replaceConeTypeOrNull(newReturnType)
|
lhsType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext)
|
||||||
isLhsNotNull = true
|
.convertToNonRawVersion()
|
||||||
}
|
result.replaceConeTypeOrNull(newReturnType)
|
||||||
|
isLhsNotNull = true
|
||||||
}
|
}
|
||||||
|
|
||||||
session.typeContext.run {
|
session.typeContext.run {
|
||||||
if (result.coneTypeSafe<ConeKotlinType>()?.isNullableType() == true
|
if (result.resolvedType.isNullableType() && !result.rhs.resolvedType.isNullableType()) {
|
||||||
&& result.rhs.coneTypeSafe<ConeKotlinType>()?.isNullableType() == false
|
|
||||||
) {
|
|
||||||
// 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(
|
||||||
|
|||||||
+7
-7
@@ -233,8 +233,8 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
// get() = delegate.getValue(thisRef, kProperty: KProperty0/1/2<..., SomeType>)
|
// get() = delegate.getValue(thisRef, kProperty: KProperty0/1/2<..., SomeType>)
|
||||||
// set() = delegate.getValue(thisRef, kProperty: KProperty0/1/2<..., SomeType>, value)
|
// set() = delegate.getValue(thisRef, kProperty: KProperty0/1/2<..., SomeType>, value)
|
||||||
val propertyReferenceAccess = resolvedArgumentMapping?.keys?.toList()?.getOrNull(1) as? FirCallableReferenceAccess ?: return
|
val propertyReferenceAccess = resolvedArgumentMapping?.keys?.toList()?.getOrNull(1) as? FirCallableReferenceAccess ?: return
|
||||||
val type = propertyReferenceAccess.coneTypeOrNull
|
val type = propertyReferenceAccess.resolvedType
|
||||||
if (type != null && property.returnTypeRef is FirResolvedTypeRef) {
|
if (property.returnTypeRef is FirResolvedTypeRef) {
|
||||||
val typeArguments = (type.type as ConeClassLikeType).typeArguments
|
val typeArguments = (type.type as ConeClassLikeType).typeArguments
|
||||||
val extensionType = property.receiverParameter?.typeRef?.coneType
|
val extensionType = property.receiverParameter?.typeRef?.coneType
|
||||||
val dispatchType = context.containingClass?.let { containingClass ->
|
val dispatchType = context.containingClass?.let { containingClass ->
|
||||||
@@ -763,7 +763,7 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
if (result.returnTypeRef is FirImplicitTypeRef) {
|
if (result.returnTypeRef is FirImplicitTypeRef) {
|
||||||
val simpleFunction = function as? FirSimpleFunction
|
val simpleFunction = function as? FirSimpleFunction
|
||||||
val returnExpression = (body?.statements?.singleOrNull() as? FirReturnExpression)?.result
|
val returnExpression = (body?.statements?.singleOrNull() as? FirReturnExpression)?.result
|
||||||
val expressionType = returnExpression?.coneTypeOrNull
|
val expressionType = returnExpression?.resolvedType
|
||||||
val returnTypeRef = expressionType
|
val returnTypeRef = expressionType
|
||||||
?.toFirResolvedTypeRef(result.returnTypeRef.source)
|
?.toFirResolvedTypeRef(result.returnTypeRef.source)
|
||||||
?.approximateDeclarationType(
|
?.approximateDeclarationType(
|
||||||
@@ -1104,7 +1104,7 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
val inferredType = if (backingField is FirDefaultPropertyBackingField) {
|
val inferredType = if (backingField is FirDefaultPropertyBackingField) {
|
||||||
propertyType
|
propertyType
|
||||||
} else {
|
} else {
|
||||||
backingField.initializer?.unwrapSmartcastExpression()?.coneTypeOrNull?.toFirResolvedTypeRef()
|
backingField.initializer?.unwrapSmartcastExpression()?.resolvedType?.toFirResolvedTypeRef()
|
||||||
}
|
}
|
||||||
val resultType = inferredType
|
val resultType = inferredType
|
||||||
?: return backingField.transformReturnTypeRef(
|
?: return backingField.transformReturnTypeRef(
|
||||||
@@ -1133,7 +1133,7 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
val resultType = when {
|
val resultType = when {
|
||||||
initializer != null -> {
|
initializer != null -> {
|
||||||
val unwrappedInitializer = initializer.unwrapSmartcastExpression()
|
val unwrappedInitializer = initializer.unwrapSmartcastExpression()
|
||||||
unwrappedInitializer.resultType?.toFirResolvedTypeRef()
|
unwrappedInitializer.resolvedType.toFirResolvedTypeRef()
|
||||||
}
|
}
|
||||||
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> variable.getter?.returnTypeRef
|
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> variable.getter?.returnTypeRef
|
||||||
else -> null
|
else -> null
|
||||||
@@ -1216,10 +1216,10 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
private val FirVariable.initializerResolved: Boolean
|
private val FirVariable.initializerResolved: Boolean
|
||||||
get() {
|
get() {
|
||||||
val initializer = initializer ?: return false
|
val initializer = initializer ?: return false
|
||||||
return initializer.coneTypeOrNull != null && initializer !is FirErrorExpression
|
return initializer.isResolved && initializer !is FirErrorExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val FirFunction.bodyResolved: Boolean
|
protected val FirFunction.bodyResolved: Boolean
|
||||||
get() = body !is FirLazyBlock && body?.coneTypeOrNull != null
|
get() = body !is FirLazyBlock && body?.isResolved == true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-18
@@ -68,7 +68,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformExpression(expression: FirExpression, data: ResolutionMode): FirStatement {
|
override fun transformExpression(expression: FirExpression, data: ResolutionMode): FirStatement {
|
||||||
if (expression.resultType == null && expression !is FirWrappedExpression) {
|
if (!expression.isResolved && expression !is FirWrappedExpression) {
|
||||||
expression.resultType = ConeErrorType(
|
expression.resultType = ConeErrorType(
|
||||||
ConeSimpleDiagnostic(
|
ConeSimpleDiagnostic(
|
||||||
"Type calculating for ${expression::class} is not supported",
|
"Type calculating for ${expression::class} is not supported",
|
||||||
@@ -95,7 +95,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
data: ResolutionMode,
|
data: ResolutionMode,
|
||||||
isUsedAsReceiver: Boolean,
|
isUsedAsReceiver: Boolean,
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
if (qualifiedAccessExpression.coneTypeOrNull != null && qualifiedAccessExpression.calleeReference !is FirSimpleNamedReference) {
|
if (qualifiedAccessExpression.isResolved && qualifiedAccessExpression.calleeReference !is FirSimpleNamedReference) {
|
||||||
return qualifiedAccessExpression
|
return qualifiedAccessExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,12 +134,12 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
is FirDelegateFieldReference -> {
|
is FirDelegateFieldReference -> {
|
||||||
val delegateFieldSymbol = callee.resolvedSymbol
|
val delegateFieldSymbol = callee.resolvedSymbol
|
||||||
qualifiedAccessExpression.resultType = delegateFieldSymbol.fir.delegate!!.coneTypeOrNull
|
qualifiedAccessExpression.resultType = delegateFieldSymbol.fir.delegate!!.resolvedType
|
||||||
qualifiedAccessExpression
|
qualifiedAccessExpression
|
||||||
}
|
}
|
||||||
is FirResolvedNamedReference,
|
is FirResolvedNamedReference,
|
||||||
is FirErrorNamedReference -> {
|
is FirErrorNamedReference -> {
|
||||||
if (qualifiedAccessExpression.coneTypeOrNull == null) {
|
if (!qualifiedAccessExpression.isResolved) {
|
||||||
storeTypeFromCallee(qualifiedAccessExpression, isLhsOfAssignment = false)
|
storeTypeFromCallee(qualifiedAccessExpression, isLhsOfAssignment = false)
|
||||||
}
|
}
|
||||||
qualifiedAccessExpression
|
qualifiedAccessExpression
|
||||||
@@ -395,7 +395,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
val calleeReference = functionCall.calleeReference
|
val calleeReference = functionCall.calleeReference
|
||||||
if (
|
if (
|
||||||
(calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) &&
|
(calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference) &&
|
||||||
functionCall.resultType == null
|
!functionCall.isResolved
|
||||||
) {
|
) {
|
||||||
storeTypeFromCallee(functionCall, isLhsOfAssignment = false)
|
storeTypeFromCallee(functionCall, isLhsOfAssignment = false)
|
||||||
}
|
}
|
||||||
@@ -724,7 +724,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
source = desugaredSource,
|
source = desugaredSource,
|
||||||
name = name,
|
name = name,
|
||||||
initializer = initializer,
|
initializer = initializer,
|
||||||
typeRef = initializer.coneTypeOrNull?.toFirResolvedTypeRef(desugaredSource),
|
typeRef = initializer.resolvedType.toFirResolvedTypeRef(desugaredSource),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun buildAndResolveOperatorCall(receiver: FirExpression): FirFunctionCall = buildFunctionCall {
|
fun buildAndResolveOperatorCall(receiver: FirExpression): FirFunctionCall = buildFunctionCall {
|
||||||
@@ -781,7 +781,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
statements += unaryVariable.toQualifiedAccess()
|
statements += unaryVariable.toQualifiedAccess()
|
||||||
}
|
}
|
||||||
}.apply {
|
}.apply {
|
||||||
replaceConeTypeOrNull((statements.last() as FirExpression).coneTypeOrNull)
|
replaceConeTypeOrNull((statements.last() as FirExpression).resolvedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (originalExpression is FirSafeCallExpression) {
|
return if (originalExpression is FirSafeCallExpression) {
|
||||||
@@ -840,7 +840,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this
|
val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this
|
||||||
if (firClass.typeParameters.isEmpty()) return this
|
if (firClass.typeParameters.isEmpty()) return this
|
||||||
|
|
||||||
val originalType = argument.unwrapSmartcastExpression().coneTypeSafe<ConeKotlinType>() ?: return this
|
val originalType = argument.unwrapSmartcastExpression().resolvedType
|
||||||
val newType = components.computeRepresentativeTypeForBareType(type, originalType)
|
val newType = components.computeRepresentativeTypeForBareType(type, originalType)
|
||||||
?: if (firClass.isLocal && (operation == FirOperation.AS || operation == FirOperation.SAFE_AS)) {
|
?: if (firClass.isLocal && (operation == FirOperation.AS || operation == FirOperation.SAFE_AS)) {
|
||||||
(firClass as FirClass).defaultType()
|
(firClass as FirClass).defaultType()
|
||||||
@@ -937,7 +937,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
// fun <K> checkNotNull(arg: K?): K
|
// fun <K> checkNotNull(arg: K?): K
|
||||||
// ...in order to get the not-nullable type of the argument.
|
// ...in order to get the not-nullable type of the argument.
|
||||||
|
|
||||||
if (checkNotNullCall.calleeReference is FirResolvedNamedReference && checkNotNullCall.resultType != null) {
|
if (checkNotNullCall.calleeReference is FirResolvedNamedReference && checkNotNullCall.isResolved) {
|
||||||
return checkNotNullCall
|
return checkNotNullCall
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,7 +981,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
||||||
) ?: typeFromCallee.type
|
) ?: typeFromCallee.type
|
||||||
} else {
|
} else {
|
||||||
desugaredAssignmentValueReferenceExpression.resultType = referencedExpression.resultType
|
desugaredAssignmentValueReferenceExpression.resultType = referencedExpression.resolvedType
|
||||||
}
|
}
|
||||||
return desugaredAssignmentValueReferenceExpression
|
return desugaredAssignmentValueReferenceExpression
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1022,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
val result = variableAssignment.transformRValue(
|
val result = variableAssignment.transformRValue(
|
||||||
transformer,
|
transformer,
|
||||||
withExpectedType(
|
withExpectedType(
|
||||||
variableAssignment.lValue.coneTypeOrNull?.toFirResolvedTypeRef() ?: FirImplicitTypeRefImplWithoutSource,
|
variableAssignment.lValue.resolvedType.toFirResolvedTypeRef(),
|
||||||
expectedTypeMismatchIsReportedInChecker = true
|
expectedTypeMismatchIsReportedInChecker = true
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -1130,11 +1130,11 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
if (!shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall)) return transformedGetClassCall
|
if (!shouldComputeTypeOfGetClassCallWithNotQualifierInLhs(getClassCall)) return transformedGetClassCall
|
||||||
val resultType = lhs.resultType
|
val resultType = lhs.resolvedType
|
||||||
if (resultType is ConeErrorType) {
|
if (resultType is ConeErrorType) {
|
||||||
resultType
|
resultType
|
||||||
} else {
|
} else {
|
||||||
ConeKotlinTypeProjectionOut(resultType!!)
|
ConeKotlinTypeProjectionOut(resultType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1291,6 +1291,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType, containingClass.symbol.toLookupTag())
|
.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType, containingClass.symbol.toLookupTag())
|
||||||
|
|
||||||
if (reference is FirThisReference && reference.boundSymbol == null) {
|
if (reference is FirThisReference && reference.boundSymbol == null) {
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
resolvedCall.dispatchReceiver?.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.toSymbol(session)?.let {
|
resolvedCall.dispatchReceiver?.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.toSymbol(session)?.let {
|
||||||
reference.replaceBoundSymbol(it)
|
reference.replaceBoundSymbol(it)
|
||||||
}
|
}
|
||||||
@@ -1518,7 +1519,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
source = lhsGetCall.explicitReceiver?.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment),
|
source = lhsGetCall.explicitReceiver?.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment),
|
||||||
name = SpecialNames.ARRAY,
|
name = SpecialNames.ARRAY,
|
||||||
initializer = initializer,
|
initializer = initializer,
|
||||||
typeRef = initializer.coneTypeOrNull?.toFirResolvedTypeRef(initializer.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)),
|
typeRef = initializer.resolvedType.toFirResolvedTypeRef(initializer.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)),
|
||||||
)
|
)
|
||||||
|
|
||||||
val indexVariables = lhsGetCall.arguments.flatMap {
|
val indexVariables = lhsGetCall.arguments.flatMap {
|
||||||
@@ -1532,7 +1533,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
source = index.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment),
|
source = index.source?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment),
|
||||||
name = SpecialNames.subscribeOperatorIndex(i),
|
name = SpecialNames.subscribeOperatorIndex(i),
|
||||||
initializer = index,
|
initializer = index,
|
||||||
typeRef = index.coneTypeOrNull?.toFirResolvedTypeRef(),
|
typeRef = index.resolvedType.toFirResolvedTypeRef(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1562,7 +1563,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
arguments += indicesQualifiedAccess.subList(i, i + varargSize)
|
arguments += indicesQualifiedAccess.subList(i, i + varargSize)
|
||||||
i += varargSize
|
i += varargSize
|
||||||
source = argument.source
|
source = argument.source
|
||||||
coneTypeOrNull = argument.coneTypeOrNull
|
coneTypeOrNull = argument.resolvedType
|
||||||
varargElementType = argument.varargElementType
|
varargElementType = argument.varargElementType
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1571,7 +1572,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
origin = FirFunctionCallOrigin.Operator
|
origin = FirFunctionCallOrigin.Operator
|
||||||
coneTypeOrNull = lhsGetCall.coneTypeOrNull
|
coneTypeOrNull = lhsGetCall.resolvedType
|
||||||
}
|
}
|
||||||
|
|
||||||
val generator = GeneratorOfPlusAssignCalls(
|
val generator = GeneratorOfPlusAssignCalls(
|
||||||
@@ -1649,7 +1650,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
data: ResolutionMode,
|
data: ResolutionMode,
|
||||||
): FirStatement {
|
): FirStatement {
|
||||||
anonymousObjectExpression.transformAnonymousObject(transformer, data)
|
anonymousObjectExpression.transformAnonymousObject(transformer, data)
|
||||||
if (anonymousObjectExpression.coneTypeOrNull == null) {
|
if (!anonymousObjectExpression.isResolved) {
|
||||||
anonymousObjectExpression.resultType = anonymousObjectExpression.anonymousObject.defaultType()
|
anonymousObjectExpression.resultType = anonymousObjectExpression.anonymousObject.defaultType()
|
||||||
}
|
}
|
||||||
dataFlowAnalyzer.exitAnonymousObjectExpression(anonymousObjectExpression)
|
dataFlowAnalyzer.exitAnonymousObjectExpression(anonymousObjectExpression)
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ class VariableStorageImpl(private val session: FirSession) : VariableStorage() {
|
|||||||
property.visibility == Visibilities.Private -> PropertyStability.STABLE_VALUE
|
property.visibility == Visibilities.Private -> PropertyStability.STABLE_VALUE
|
||||||
property.modality != Modality.FINAL -> {
|
property.modality != Modality.FINAL -> {
|
||||||
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccessExpression)?.dispatchReceiver ?: return null
|
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccessExpression)?.dispatchReceiver ?: return null
|
||||||
|
|
||||||
|
@OptIn(UnresolvedExpressionTypeAccess::class)
|
||||||
val receiverType = dispatchReceiver.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return null
|
val receiverType = dispatchReceiver.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return null
|
||||||
val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return null
|
val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return null
|
||||||
when (val receiverFir = receiverSymbol.fir) {
|
when (val receiverFir = receiverSymbol.fir) {
|
||||||
|
|||||||
@@ -860,6 +860,7 @@ class WhenSubjectExpressionExitNode(owner: ControlFlowGraph, override val fir: F
|
|||||||
|
|
||||||
object FirStub : FirExpression() {
|
object FirStub : FirExpression() {
|
||||||
override val source: KtSourceElement? get() = null
|
override val source: KtSourceElement? get() = null
|
||||||
|
@UnresolvedExpressionTypeAccess
|
||||||
override val coneTypeOrNull: ConeKotlinType = StandardClassIds.Nothing.constructClassLikeType()
|
override val coneTypeOrNull: ConeKotlinType = StandardClassIds.Nothing.constructClassLikeType()
|
||||||
override val annotations: List<FirAnnotation> get() = listOf()
|
override val annotations: List<FirAnnotation> get() = listOf()
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -12,16 +12,16 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
|
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.UnresolvedExpressionTypeAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.unexpandedClassId
|
import org.jetbrains.kotlin.fir.expressions.unexpandedClassId
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.toEffectiveVisibility
|
import org.jetbrains.kotlin.fir.toEffectiveVisibility
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.resolvedType
|
||||||
import org.jetbrains.kotlin.fir.types.toLookupTag
|
import org.jetbrains.kotlin.fir.types.toLookupTag
|
||||||
import org.jetbrains.kotlin.fir.types.typeContext
|
import org.jetbrains.kotlin.fir.types.typeContext
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
@@ -57,7 +57,7 @@ fun computePublishedApiEffectiveVisibility(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
): EffectiveVisibility? {
|
): EffectiveVisibility? {
|
||||||
val hasPublishedApiAnnotation = annotations.any {
|
val hasPublishedApiAnnotation = annotations.any {
|
||||||
it.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.classId == StandardClassIds.Annotations.PublishedApi
|
(it.resolvedType as? ConeClassLikeType)?.lookupTag?.classId == StandardClassIds.Annotations.PublishedApi
|
||||||
}
|
}
|
||||||
|
|
||||||
return computePublishedApiEffectiveVisibility(
|
return computePublishedApiEffectiveVisibility(
|
||||||
|
|||||||
Reference in New Issue
Block a user