Refactoring: extract method to detect redundant is out
This commit is contained in:
@@ -350,6 +350,15 @@ public class DataFlowAnalyzer {
|
|||||||
@NotNull ResolutionContext c
|
@NotNull ResolutionContext c
|
||||||
) {
|
) {
|
||||||
DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, type, c);
|
DataFlowValue dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, type, c);
|
||||||
|
return getAllPossibleTypes(type, c, dataFlowValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static Collection<KotlinType> getAllPossibleTypes(
|
||||||
|
@NotNull KotlinType type,
|
||||||
|
@NotNull ResolutionContext c,
|
||||||
|
@NotNull DataFlowValue dataFlowValue
|
||||||
|
) {
|
||||||
Collection<KotlinType> possibleTypes = Sets.newHashSet(type);
|
Collection<KotlinType> possibleTypes = Sets.newHashSet(type);
|
||||||
possibleTypes.addAll(c.dataFlowInfo.getStableTypes(dataFlowValue));
|
possibleTypes.addAll(c.dataFlowInfo.getStableTypes(dataFlowValue));
|
||||||
return possibleTypes;
|
return possibleTypes;
|
||||||
|
|||||||
+21
-10
@@ -436,21 +436,15 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
|
|||||||
if (targetDescriptor != null && DescriptorUtils.isEnumEntry(targetDescriptor)) {
|
if (targetDescriptor != null && DescriptorUtils.isEnumEntry(targetDescriptor)) {
|
||||||
context.trace.report(IS_ENUM_ENTRY.on(typeReferenceAfterIs))
|
context.trace.report(IS_ENUM_ENTRY.on(typeReferenceAfterIs))
|
||||||
}
|
}
|
||||||
val subjectTypeHasError = subjectType.containsError()
|
if (!subjectType.containsError() && !TypeUtils.isNullableType(subjectType) && targetType.isMarkedNullable) {
|
||||||
if (!subjectTypeHasError && !TypeUtils.isNullableType(subjectType) && targetType.isMarkedNullable) {
|
|
||||||
val element = typeReferenceAfterIs.typeElement
|
val element = typeReferenceAfterIs.typeElement
|
||||||
assert(element is KtNullableType) { "element must be instance of " + KtNullableType::class.java.name }
|
assert(element is KtNullableType) { "element must be instance of " + KtNullableType::class.java.name }
|
||||||
context.trace.report(Errors.USELESS_NULLABLE_CHECK.on(element as KtNullableType))
|
context.trace.report(Errors.USELESS_NULLABLE_CHECK.on(element as KtNullableType))
|
||||||
}
|
}
|
||||||
checkTypeCompatibility(context, targetType, subjectType, typeReferenceAfterIs)
|
checkTypeCompatibility(context, targetType, subjectType, typeReferenceAfterIs)
|
||||||
if (!subjectTypeHasError && !targetType.containsError()) {
|
|
||||||
val possibleTypes = hashSetOf(subjectType)
|
detectRedundantIs(context, subjectType, targetType, isCheck, negated, subjectDataFlowValue)
|
||||||
possibleTypes.addAll(context.dataFlowInfo.getStableTypes(subjectDataFlowValue))
|
|
||||||
val intersection = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, possibleTypes.map { it.upperIfFlexible() })
|
|
||||||
if (intersection?.isSubtypeOf(targetType) ?: false) {
|
|
||||||
context.trace.report(Errors.USELESS_IS_CHECK.on(isCheck, !negated))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (CastDiagnosticsUtil.isCastErased(subjectType, targetType, KotlinTypeChecker.DEFAULT)) {
|
if (CastDiagnosticsUtil.isCastErased(subjectType, targetType, KotlinTypeChecker.DEFAULT)) {
|
||||||
context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(typeReferenceAfterIs, targetType))
|
context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(typeReferenceAfterIs, targetType))
|
||||||
}
|
}
|
||||||
@@ -459,6 +453,23 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun detectRedundantIs(
|
||||||
|
context: ExpressionTypingContext,
|
||||||
|
subjectType: KotlinType,
|
||||||
|
targetType: KotlinType,
|
||||||
|
isCheck: KtElement,
|
||||||
|
negated: Boolean,
|
||||||
|
subjectDataFlowValue: DataFlowValue
|
||||||
|
) {
|
||||||
|
if (subjectType.containsError() || targetType.containsError()) return
|
||||||
|
|
||||||
|
val possibleTypes = DataFlowAnalyzer.getAllPossibleTypes(subjectType, context, subjectDataFlowValue)
|
||||||
|
val intersection = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, possibleTypes.map { it.upperIfFlexible() })
|
||||||
|
if (intersection?.isSubtypeOf(targetType) ?: false) {
|
||||||
|
context.trace.report(Errors.USELESS_IS_CHECK.on(isCheck, !negated))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun noChange(context: ExpressionTypingContext) = ConditionalDataFlowInfo(context.dataFlowInfo)
|
private fun noChange(context: ExpressionTypingContext) = ConditionalDataFlowInfo(context.dataFlowInfo)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user