Refactoring: extract method to detect redundant is out

This commit is contained in:
Mikhail Zarechenskiy
2017-05-10 15:06:52 +03:00
parent cd24adac32
commit b323d2b24a
2 changed files with 30 additions and 10 deletions
@@ -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;
@@ -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)
/*