Refactoring: extract method to detect redundant is out
This commit is contained in:
@@ -350,6 +350,15 @@ public class DataFlowAnalyzer {
|
||||
@NotNull ResolutionContext 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);
|
||||
possibleTypes.addAll(c.dataFlowInfo.getStableTypes(dataFlowValue));
|
||||
return possibleTypes;
|
||||
|
||||
+21
-10
@@ -436,21 +436,15 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
|
||||
if (targetDescriptor != null && DescriptorUtils.isEnumEntry(targetDescriptor)) {
|
||||
context.trace.report(IS_ENUM_ENTRY.on(typeReferenceAfterIs))
|
||||
}
|
||||
val subjectTypeHasError = subjectType.containsError()
|
||||
if (!subjectTypeHasError && !TypeUtils.isNullableType(subjectType) && targetType.isMarkedNullable) {
|
||||
if (!subjectType.containsError() && !TypeUtils.isNullableType(subjectType) && targetType.isMarkedNullable) {
|
||||
val element = typeReferenceAfterIs.typeElement
|
||||
assert(element is KtNullableType) { "element must be instance of " + KtNullableType::class.java.name }
|
||||
context.trace.report(Errors.USELESS_NULLABLE_CHECK.on(element as KtNullableType))
|
||||
}
|
||||
checkTypeCompatibility(context, targetType, subjectType, typeReferenceAfterIs)
|
||||
if (!subjectTypeHasError && !targetType.containsError()) {
|
||||
val possibleTypes = hashSetOf(subjectType)
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
detectRedundantIs(context, subjectType, targetType, isCheck, negated, subjectDataFlowValue)
|
||||
|
||||
if (CastDiagnosticsUtil.isCastErased(subjectType, targetType, KotlinTypeChecker.DEFAULT)) {
|
||||
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)
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user