Support warning about useless cast on safe cast

#KT-13348 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2017-04-07 04:56:59 +03:00
parent 107879a78a
commit 7f287a4230
12 changed files with 56 additions and 23 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -541,6 +541,14 @@ public class KtPsiUtil {
((KtBinaryExpression) element).getOperationToken().equals(KtTokens.EQ);
}
public static boolean isSafeCast(@NotNull KtBinaryExpressionWithTypeRHS expression) {
return expression.getOperationReference().getReferencedNameElementType() == KtTokens.AS_SAFE;
}
public static boolean isUnsafeCast(@NotNull KtBinaryExpressionWithTypeRHS expression) {
return expression.getOperationReference().getReferencedNameElementType() == KtTokens.AS_KEYWORD;
}
public static boolean checkVariableDeclarationInBlock(@NotNull KtBlockExpression block, @NotNull String varName) {
for (KtExpression element : block.getStatements()) {
if (element instanceof KtVariableDeclaration) {
@@ -26,7 +26,6 @@ import kotlin.TuplesKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
@@ -395,13 +394,16 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@NotNull KotlinType actualType,
@NotNull KotlinTypeChecker typeChecker
) {
// Here: x as? Type <=> x as Type?
KotlinType refinedTargetType = KtPsiUtil.isSafeCast(expression) ? TypeUtils.makeNullable(targetType) : targetType;
Collection<KotlinType> possibleTypes = DataFlowAnalyzer.getAllPossibleTypes(expression.getLeft(), actualType, context);
KotlinType intersectedType = TypeIntersector.intersectTypes(typeChecker, possibleTypes);
if (intersectedType == null) return false;
return shouldCheckForExactType(expression, context.expectedType)
? isExactTypeCast(intersectedType, targetType)
: isUpcast(intersectedType, targetType, typeChecker);
? isExactTypeCast(intersectedType, refinedTargetType)
: isUpcast(intersectedType, refinedTargetType, typeChecker);
}
private static boolean shouldCheckForExactType(KtBinaryExpressionWithTypeRHS expression, KotlinType expectedType) {