Refactoring: context instead of trace in WhenChecker and around
This commit is contained in:
+3
-3
@@ -104,9 +104,9 @@ class JavaNullabilityWarningsChecker : AdditionalTypeChecker {
|
|||||||
val type = expression.subjectExpression?.let { c.trace.getType(it) } ?: return
|
val type = expression.subjectExpression?.let { c.trace.getType(it) } ?: return
|
||||||
if (type.isFlexible() && TypeUtils.isNullableType(type.flexibility().upperBound) && !type.annotations.isMarkedNotNull()) {
|
if (type.isFlexible() && TypeUtils.isNullableType(type.flexibility().upperBound) && !type.annotations.isMarkedNotNull()) {
|
||||||
val enumClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfEnum(type) ?: return
|
val enumClassDescriptor = WhenChecker.getClassDescriptorOfTypeIfEnum(type) ?: return
|
||||||
|
val context = c.trace.bindingContext
|
||||||
if (WhenChecker.getEnumMissingCases(expression, c.trace, enumClassDescriptor).isEmpty()
|
if (WhenChecker.getEnumMissingCases(expression, context, enumClassDescriptor).isEmpty()
|
||||||
&& !WhenChecker.containsNullCase(expression, c.trace)) {
|
&& !WhenChecker.containsNullCase(expression, context)) {
|
||||||
|
|
||||||
c.trace.report(ErrorsJvm.WHEN_ENUM_CAN_BE_NULL_IN_JAVA.on(expression.getSubjectExpression()))
|
c.trace.report(ErrorsJvm.WHEN_ENUM_CAN_BE_NULL_IN_JAVA.on(expression.getSubjectExpression()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -743,7 +743,8 @@ public class ControlFlowInformationProvider {
|
|||||||
KtWhenExpression whenExpression = (KtWhenExpression) element;
|
KtWhenExpression whenExpression = (KtWhenExpression) element;
|
||||||
if (whenExpression.getElseExpression() != null) continue;
|
if (whenExpression.getElseExpression() != null) continue;
|
||||||
|
|
||||||
List<WhenMissingCase> necessaryCases = WhenChecker.getNecessaryCases(whenExpression, trace);
|
BindingContext context = trace.getBindingContext();
|
||||||
|
List<WhenMissingCase> necessaryCases = WhenChecker.getNecessaryCases(whenExpression, context);
|
||||||
if (!necessaryCases.isEmpty()) {
|
if (!necessaryCases.isEmpty()) {
|
||||||
trace.report(NO_ELSE_IN_WHEN.on(whenExpression, necessaryCases));
|
trace.report(NO_ELSE_IN_WHEN.on(whenExpression, necessaryCases));
|
||||||
}
|
}
|
||||||
@@ -752,7 +753,7 @@ public class ControlFlowInformationProvider {
|
|||||||
trace.getType(whenExpression.getSubjectExpression()));
|
trace.getType(whenExpression.getSubjectExpression()));
|
||||||
if (enumClassDescriptor != null) {
|
if (enumClassDescriptor != null) {
|
||||||
List<WhenMissingCase> missingCases = WhenChecker.getEnumMissingCases(
|
List<WhenMissingCase> missingCases = WhenChecker.getEnumMissingCases(
|
||||||
whenExpression, trace, enumClassDescriptor
|
whenExpression, context, enumClassDescriptor
|
||||||
);
|
);
|
||||||
if (!missingCases.isEmpty()) {
|
if (!missingCases.isEmpty()) {
|
||||||
trace.report(NON_EXHAUSTIVE_WHEN.on(whenExpression, missingCases));
|
trace.report(NON_EXHAUSTIVE_WHEN.on(whenExpression, missingCases));
|
||||||
|
|||||||
@@ -802,8 +802,7 @@ public class ControlFlowProcessor {
|
|||||||
generateInstructions(condition);
|
generateInstructions(condition);
|
||||||
}
|
}
|
||||||
mark(expression);
|
mark(expression);
|
||||||
boolean conditionIsTrueConstant = CompileTimeConstantUtils.canBeReducedToBooleanConstant(condition, trace, true);
|
if (!CompileTimeConstantUtils.canBeReducedToBooleanConstant(condition, trace.getBindingContext(), true)) {
|
||||||
if (!conditionIsTrueConstant) {
|
|
||||||
builder.jumpOnFalse(loopInfo.getExitPoint(), expression, builder.getBoundValue(condition));
|
builder.jumpOnFalse(loopInfo.getExitPoint(), expression, builder.getBoundValue(condition));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -52,12 +52,12 @@ val List<WhenMissingCase>.hasUnknown: Boolean
|
|||||||
private interface WhenExhaustivenessChecker {
|
private interface WhenExhaustivenessChecker {
|
||||||
fun getMissingCases(
|
fun getMissingCases(
|
||||||
expression: KtWhenExpression,
|
expression: KtWhenExpression,
|
||||||
trace: BindingTrace,
|
context: BindingContext,
|
||||||
subjectDescriptor: ClassDescriptor?,
|
subjectDescriptor: ClassDescriptor?,
|
||||||
nullable: Boolean
|
nullable: Boolean
|
||||||
): List<WhenMissingCase>
|
): List<WhenMissingCase>
|
||||||
|
|
||||||
fun isApplicable(subjectType: KotlinType, trace: BindingTrace): Boolean = false
|
fun isApplicable(subjectType: KotlinType): Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private object NullMissingCase : WhenMissingCase {
|
private object NullMissingCase : WhenMissingCase {
|
||||||
@@ -65,17 +65,17 @@ private object NullMissingCase : WhenMissingCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private object WhenOnNullableExhaustivenessChecker : WhenExhaustivenessChecker {
|
private object WhenOnNullableExhaustivenessChecker : WhenExhaustivenessChecker {
|
||||||
override fun getMissingCases(expression: KtWhenExpression, trace: BindingTrace, subjectDescriptor: ClassDescriptor?, nullable: Boolean) =
|
override fun getMissingCases(expression: KtWhenExpression, context: BindingContext, subjectDescriptor: ClassDescriptor?, nullable: Boolean) =
|
||||||
if (nullable) getNullCaseIfMissing(expression, trace) else listOf()
|
if (nullable) getNullCaseIfMissing(expression, context) else listOf()
|
||||||
|
|
||||||
override fun isApplicable(subjectType: KotlinType, trace: BindingTrace): Boolean = TypeUtils.isNullableType(subjectType)
|
override fun isApplicable(subjectType: KotlinType): Boolean = TypeUtils.isNullableType(subjectType)
|
||||||
|
|
||||||
private fun getNullCaseIfMissing(expression: KtWhenExpression, trace: BindingTrace): List<WhenMissingCase> {
|
private fun getNullCaseIfMissing(expression: KtWhenExpression, context: BindingContext): List<WhenMissingCase> {
|
||||||
for (entry in expression.entries) {
|
for (entry in expression.entries) {
|
||||||
for (condition in entry.conditions) {
|
for (condition in entry.conditions) {
|
||||||
if (condition is KtWhenConditionWithExpression) {
|
if (condition is KtWhenConditionWithExpression) {
|
||||||
condition.expression?.let {
|
condition.expression?.let {
|
||||||
val type = trace.bindingContext.getType(it)
|
val type = context.getType(it)
|
||||||
if (type != null && KotlinBuiltIns.isNullableNothing(type)) {
|
if (type != null && KotlinBuiltIns.isNullableNothing(type)) {
|
||||||
return listOf()
|
return listOf()
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ private class BooleanMissingCase(val b: Boolean) : WhenMissingCase {
|
|||||||
private object WhenOnBooleanExhaustivenessChecker : WhenExhaustivenessChecker {
|
private object WhenOnBooleanExhaustivenessChecker : WhenExhaustivenessChecker {
|
||||||
override fun getMissingCases(
|
override fun getMissingCases(
|
||||||
expression: KtWhenExpression,
|
expression: KtWhenExpression,
|
||||||
trace: BindingTrace,
|
context: BindingContext,
|
||||||
subjectDescriptor: ClassDescriptor?,
|
subjectDescriptor: ClassDescriptor?,
|
||||||
nullable: Boolean
|
nullable: Boolean
|
||||||
): List<WhenMissingCase> {
|
): List<WhenMissingCase> {
|
||||||
@@ -105,8 +105,8 @@ private object WhenOnBooleanExhaustivenessChecker : WhenExhaustivenessChecker {
|
|||||||
for (whenCondition in whenEntry.conditions) {
|
for (whenCondition in whenEntry.conditions) {
|
||||||
if (whenCondition is KtWhenConditionWithExpression) {
|
if (whenCondition is KtWhenConditionWithExpression) {
|
||||||
val whenExpression = whenCondition.expression
|
val whenExpression = whenCondition.expression
|
||||||
if (CompileTimeConstantUtils.canBeReducedToBooleanConstant(whenExpression, trace, true)) containsTrue = true
|
if (CompileTimeConstantUtils.canBeReducedToBooleanConstant(whenExpression, context, true)) containsTrue = true
|
||||||
if (CompileTimeConstantUtils.canBeReducedToBooleanConstant(whenExpression, trace, false)) containsFalse = true
|
if (CompileTimeConstantUtils.canBeReducedToBooleanConstant(whenExpression, context, false)) containsFalse = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ private object WhenOnBooleanExhaustivenessChecker : WhenExhaustivenessChecker {
|
|||||||
(if (!containsFalse) listOf(BooleanMissingCase(false)) else listOf())
|
(if (!containsFalse) listOf(BooleanMissingCase(false)) else listOf())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicable(subjectType: KotlinType, trace: BindingTrace): Boolean {
|
override fun isApplicable(subjectType: KotlinType): Boolean {
|
||||||
return KotlinBuiltIns.isBoolean(TypeUtils.makeNotNullable(subjectType))
|
return KotlinBuiltIns.isBoolean(TypeUtils.makeNotNullable(subjectType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,7 +134,7 @@ private abstract class WhenOnClassExhaustivenessChecker : WhenExhaustivenessChec
|
|||||||
protected fun getMissingClassCases(
|
protected fun getMissingClassCases(
|
||||||
whenExpression: KtWhenExpression,
|
whenExpression: KtWhenExpression,
|
||||||
memberDescriptors: Set<ClassDescriptor>,
|
memberDescriptors: Set<ClassDescriptor>,
|
||||||
trace: BindingTrace
|
context: BindingContext
|
||||||
): List<WhenMissingCase> {
|
): List<WhenMissingCase> {
|
||||||
// when on empty enum / sealed is considered non-exhaustive, see test whenOnEmptySealed
|
// when on empty enum / sealed is considered non-exhaustive, see test whenOnEmptySealed
|
||||||
if (memberDescriptors.isEmpty()) return listOf(UnknownMissingCase)
|
if (memberDescriptors.isEmpty()) return listOf(UnknownMissingCase)
|
||||||
@@ -144,7 +144,7 @@ private abstract class WhenOnClassExhaustivenessChecker : WhenExhaustivenessChec
|
|||||||
var negated = false
|
var negated = false
|
||||||
var checkedDescriptor: ClassDescriptor? = null
|
var checkedDescriptor: ClassDescriptor? = null
|
||||||
if (condition is KtWhenConditionIsPattern) {
|
if (condition is KtWhenConditionIsPattern) {
|
||||||
val checkedType = trace.get(BindingContext.TYPE, condition.typeReference)
|
val checkedType = context.get(BindingContext.TYPE, condition.typeReference)
|
||||||
if (checkedType != null) {
|
if (checkedType != null) {
|
||||||
checkedDescriptor = TypeUtils.getClassDescriptor(checkedType)
|
checkedDescriptor = TypeUtils.getClassDescriptor(checkedType)
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ private abstract class WhenOnClassExhaustivenessChecker : WhenExhaustivenessChec
|
|||||||
if (condition.expression != null) {
|
if (condition.expression != null) {
|
||||||
val reference = getReference(condition.expression)
|
val reference = getReference(condition.expression)
|
||||||
if (reference != null) {
|
if (reference != null) {
|
||||||
val target = trace.get(BindingContext.REFERENCE_TARGET, reference)
|
val target = context.get(BindingContext.REFERENCE_TARGET, reference)
|
||||||
if (target is ClassDescriptor) {
|
if (target is ClassDescriptor) {
|
||||||
checkedDescriptor = target
|
checkedDescriptor = target
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ private abstract class WhenOnClassExhaustivenessChecker : WhenExhaustivenessChec
|
|||||||
private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
||||||
override fun getMissingCases(
|
override fun getMissingCases(
|
||||||
expression: KtWhenExpression,
|
expression: KtWhenExpression,
|
||||||
trace: BindingTrace,
|
context: BindingContext,
|
||||||
subjectDescriptor: ClassDescriptor?,
|
subjectDescriptor: ClassDescriptor?,
|
||||||
nullable: Boolean
|
nullable: Boolean
|
||||||
): List<WhenMissingCase> {
|
): List<WhenMissingCase> {
|
||||||
@@ -198,10 +198,10 @@ private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecke
|
|||||||
.filter { isEnumEntry(it) }
|
.filter { isEnumEntry(it) }
|
||||||
.filterIsInstance<ClassDescriptor>()
|
.filterIsInstance<ClassDescriptor>()
|
||||||
.toSet()
|
.toSet()
|
||||||
return getMissingClassCases(expression, entryDescriptors, trace)
|
return getMissingClassCases(expression, entryDescriptors, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicable(subjectType: KotlinType, trace: BindingTrace): Boolean {
|
override fun isApplicable(subjectType: KotlinType): Boolean {
|
||||||
return WhenChecker.getClassDescriptorOfTypeIfEnum(subjectType) != null
|
return WhenChecker.getClassDescriptorOfTypeIfEnum(subjectType) != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ private object WhenOnEnumExhaustivenessChecker : WhenOnClassExhaustivenessChecke
|
|||||||
private object WhenOnSealedExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
private object WhenOnSealedExhaustivenessChecker : WhenOnClassExhaustivenessChecker() {
|
||||||
override fun getMissingCases(
|
override fun getMissingCases(
|
||||||
expression: KtWhenExpression,
|
expression: KtWhenExpression,
|
||||||
trace: BindingTrace,
|
context: BindingContext,
|
||||||
subjectDescriptor: ClassDescriptor?,
|
subjectDescriptor: ClassDescriptor?,
|
||||||
nullable: Boolean
|
nullable: Boolean
|
||||||
): List<WhenMissingCase> {
|
): List<WhenMissingCase> {
|
||||||
@@ -220,10 +220,10 @@ private object WhenOnSealedExhaustivenessChecker : WhenOnClassExhaustivenessChec
|
|||||||
val memberClassDescriptors = LinkedHashSet<ClassDescriptor>()
|
val memberClassDescriptors = LinkedHashSet<ClassDescriptor>()
|
||||||
collectNestedSubclasses(subjectDescriptor!!, subjectDescriptor, memberClassDescriptors)
|
collectNestedSubclasses(subjectDescriptor!!, subjectDescriptor, memberClassDescriptors)
|
||||||
// When on a sealed class without derived members is considered non-exhaustive (see test WhenOnEmptySealed)
|
// When on a sealed class without derived members is considered non-exhaustive (see test WhenOnEmptySealed)
|
||||||
return getMissingClassCases(expression, memberClassDescriptors, trace)
|
return getMissingClassCases(expression, memberClassDescriptors, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isApplicable(subjectType: KotlinType, trace: BindingTrace): Boolean {
|
override fun isApplicable(subjectType: KotlinType): Boolean {
|
||||||
return TypeUtils.getClassDescriptor(subjectType)?.modality == Modality.SEALED
|
return TypeUtils.getClassDescriptor(subjectType)?.modality == Modality.SEALED
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +251,8 @@ object WhenChecker {
|
|||||||
WhenOnNullableExhaustivenessChecker)
|
WhenOnNullableExhaustivenessChecker)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getNecessaryCases(expression: KtWhenExpression, trace: BindingTrace) =
|
fun getNecessaryCases(expression: KtWhenExpression, context: BindingContext) =
|
||||||
if (expression.isUsedAsExpression(trace.bindingContext)) getMissingCases(expression, trace)
|
if (expression.isUsedAsExpression(context)) getMissingCases(expression, context)
|
||||||
else listOf()
|
else listOf()
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -274,9 +274,9 @@ object WhenChecker {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getEnumMissingCases(
|
fun getEnumMissingCases(
|
||||||
expression: KtWhenExpression,
|
expression: KtWhenExpression,
|
||||||
trace: BindingTrace,
|
context: BindingContext,
|
||||||
enumClassDescriptor: ClassDescriptor
|
enumClassDescriptor: ClassDescriptor
|
||||||
) = WhenOnEnumExhaustivenessChecker.getMissingCases(expression, trace, enumClassDescriptor, false)
|
) = WhenOnEnumExhaustivenessChecker.getMissingCases(expression, context, enumClassDescriptor, false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It's assumed that function is called for a final type. In this case the only possible smart cast is to not nullable type.
|
* It's assumed that function is called for a final type. In this case the only possible smart cast is to not nullable type.
|
||||||
@@ -285,11 +285,12 @@ object WhenChecker {
|
|||||||
private fun isNullableTypeWithoutPossibleSmartCast(
|
private fun isNullableTypeWithoutPossibleSmartCast(
|
||||||
expression: KtExpression?,
|
expression: KtExpression?,
|
||||||
type: KotlinType,
|
type: KotlinType,
|
||||||
trace: BindingTrace): Boolean {
|
context: BindingContext
|
||||||
|
): Boolean {
|
||||||
if (expression == null) return false // Normally should not happen
|
if (expression == null) return false // Normally should not happen
|
||||||
if (!TypeUtils.isNullableType(type)) return false
|
if (!TypeUtils.isNullableType(type)) return false
|
||||||
// We cannot read data flow information here due to lack of inputs (module descriptor is necessary)
|
// We cannot read data flow information here due to lack of inputs (module descriptor is necessary)
|
||||||
if (trace.get(BindingContext.SMARTCAST, expression) != null) {
|
if (context.get(BindingContext.SMARTCAST, expression) != null) {
|
||||||
// We have smart cast from enum or boolean to something
|
// We have smart cast from enum or boolean to something
|
||||||
// Not very nice but we *can* decide it was smart cast to not-null
|
// Not very nice but we *can* decide it was smart cast to not-null
|
||||||
// because both enum and boolean are final
|
// because both enum and boolean are final
|
||||||
@@ -298,17 +299,17 @@ object WhenChecker {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMissingCases(expression: KtWhenExpression, trace: BindingTrace): List<WhenMissingCase> {
|
private fun getMissingCases(expression: KtWhenExpression, context: BindingContext): List<WhenMissingCase> {
|
||||||
val type = whenSubjectType(expression, trace.bindingContext) ?: return listOf(UnknownMissingCase)
|
val type = whenSubjectType(expression, context) ?: return listOf(UnknownMissingCase)
|
||||||
val nullable = !type.isFlexible() && isNullableTypeWithoutPossibleSmartCast(expression.subjectExpression, type, trace)
|
val nullable = !type.isFlexible() && isNullableTypeWithoutPossibleSmartCast(expression.subjectExpression, type, context)
|
||||||
val checkers = exhaustivenessCheckers.filter { it.isApplicable(type, trace) }
|
val checkers = exhaustivenessCheckers.filter { it.isApplicable(type) }
|
||||||
if (checkers.isEmpty()) return listOf(UnknownMissingCase)
|
if (checkers.isEmpty()) return listOf(UnknownMissingCase)
|
||||||
return checkers.map { it.getMissingCases(expression, trace, TypeUtils.getClassDescriptor(type), nullable) }.flatten()
|
return checkers.map { it.getMissingCases(expression, context, TypeUtils.getClassDescriptor(type), nullable) }.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isWhenExhaustive(expression: KtWhenExpression, trace: BindingTrace) =
|
fun isWhenExhaustive(expression: KtWhenExpression, trace: BindingTrace) =
|
||||||
if (getMissingCases(expression, trace).isEmpty()) {
|
if (getMissingCases(expression, trace.bindingContext).isEmpty()) {
|
||||||
trace.record(BindingContext.EXHAUSTIVE_WHEN, expression)
|
trace.record(BindingContext.EXHAUSTIVE_WHEN, expression)
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@@ -316,8 +317,8 @@ object WhenChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun containsNullCase(expression: KtWhenExpression, trace: BindingTrace) =
|
fun containsNullCase(expression: KtWhenExpression, context: BindingContext) =
|
||||||
WhenOnNullableExhaustivenessChecker.getMissingCases(expression, trace, null, true).isEmpty()
|
WhenOnNullableExhaustivenessChecker.getMissingCases(expression, context, null, true).isEmpty()
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun checkDeprecatedWhenSyntax(trace: BindingTrace, expression: KtWhenExpression) {
|
fun checkDeprecatedWhenSyntax(trace: BindingTrace, expression: KtWhenExpression) {
|
||||||
|
|||||||
@@ -109,14 +109,14 @@ public class CompileTimeConstantUtils {
|
|||||||
|
|
||||||
public static boolean canBeReducedToBooleanConstant(
|
public static boolean canBeReducedToBooleanConstant(
|
||||||
@Nullable KtExpression expression,
|
@Nullable KtExpression expression,
|
||||||
@NotNull BindingTrace trace,
|
@NotNull BindingContext context,
|
||||||
@Nullable Boolean expectedValue
|
@Nullable Boolean expectedValue
|
||||||
) {
|
) {
|
||||||
KtExpression effectiveExpression = KtPsiUtil.deparenthesize(expression);
|
KtExpression effectiveExpression = KtPsiUtil.deparenthesize(expression);
|
||||||
|
|
||||||
if (effectiveExpression == null) return false;
|
if (effectiveExpression == null) return false;
|
||||||
|
|
||||||
CompileTimeConstant<?> compileTimeConstant = ConstantExpressionEvaluator.getConstant(effectiveExpression, trace.getBindingContext());
|
CompileTimeConstant<?> compileTimeConstant = ConstantExpressionEvaluator.getConstant(effectiveExpression, context);
|
||||||
if (!(compileTimeConstant instanceof TypedCompileTimeConstant) || compileTimeConstant.getUsesVariableAsConstant()) return false;
|
if (!(compileTimeConstant instanceof TypedCompileTimeConstant) || compileTimeConstant.getUsesVariableAsConstant()) return false;
|
||||||
|
|
||||||
ConstantValue constantValue = ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue();
|
ConstantValue constantValue = ((TypedCompileTimeConstant) compileTimeConstant).getConstantValue();
|
||||||
|
|||||||
+1
-1
@@ -93,7 +93,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
loopBreakContinuePossible = typeInfo.getJumpOutPossible();
|
loopBreakContinuePossible = typeInfo.getJumpOutPossible();
|
||||||
subjectType = typeInfo.getType();
|
subjectType = typeInfo.getType();
|
||||||
assert subjectType != null;
|
assert subjectType != null;
|
||||||
if (TypeUtils.isNullableType(subjectType) && !WhenChecker.containsNullCase(expression, context.trace)) {
|
if (TypeUtils.isNullableType(subjectType) && !WhenChecker.containsNullCase(expression, context.trace.getBindingContext())) {
|
||||||
TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "Temporary trace for when subject nullability");
|
TemporaryBindingTrace trace = TemporaryBindingTrace.create(context.trace, "Temporary trace for when subject nullability");
|
||||||
ExpressionTypingContext subjectContext =
|
ExpressionTypingContext subjectContext =
|
||||||
context.replaceExpectedType(TypeUtils.makeNotNullable(subjectType)).replaceBindingTrace(trace);
|
context.replaceExpectedType(TypeUtils.makeNotNullable(subjectType)).replaceBindingTrace(trace);
|
||||||
|
|||||||
+1
-3
@@ -124,9 +124,7 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
|||||||
private fun simplifyExpression(expression: KtExpression) = expression.replaced(toSimplifiedExpression(expression))
|
private fun simplifyExpression(expression: KtExpression) = expression.replaced(toSimplifiedExpression(expression))
|
||||||
|
|
||||||
private fun KtExpression.canBeReducedToBooleanConstant(constant: Boolean?): Boolean {
|
private fun KtExpression.canBeReducedToBooleanConstant(constant: Boolean?): Boolean {
|
||||||
val bindingContext = this.analyze()
|
return CompileTimeConstantUtils.canBeReducedToBooleanConstant(this, this.analyze(), constant)
|
||||||
val trace = DelegatingBindingTrace(bindingContext, "trace for constant check")
|
|
||||||
return CompileTimeConstantUtils.canBeReducedToBooleanConstant(this, trace, constant)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtExpression.canBeReducedToTrue() = canBeReducedToBooleanConstant(true)
|
private fun KtExpression.canBeReducedToTrue() = canBeReducedToBooleanConstant(true)
|
||||||
|
|||||||
Reference in New Issue
Block a user