IG: check if constructor parameter type matches (IDEA-168691)

This commit is contained in:
Bas Leijdekkers
2017-03-25 23:15:41 +01:00
parent b611999097
commit ce61ec7d65
3 changed files with 32 additions and 13 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-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.
@@ -18,15 +18,14 @@ package com.siyeh.ig.errorhandling;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.controlFlow.DefUseUtil;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.DeclarationSearchUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import com.siyeh.ig.psiutils.DeclarationSearchUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -78,7 +77,7 @@ public class UnnecessaryInitCauseInspectionBase extends BaseInspection {
}
final PsiExpression qualifier = ParenthesesUtils.stripParentheses(methodExpression.getQualifierExpression());
final PsiNewExpression newExpression = findNewExpression(qualifier);
if (!isCauseConstructorAvailable(newExpression) || !canExpressionBeMovedBackwards(argument, newExpression)) {
if (!isCauseConstructorAvailable(newExpression, argument.getType()) || !canExpressionBeMovedBackwards(argument, newExpression)) {
return;
}
registerMethodCallError(expression);
@@ -114,8 +113,8 @@ public class UnnecessaryInitCauseInspectionBase extends BaseInspection {
return result.get().booleanValue();
}
public static boolean isCauseConstructorAvailable(PsiNewExpression newExpression) {
if (newExpression == null) {
public static boolean isCauseConstructorAvailable(PsiNewExpression newExpression, PsiType causeType) {
if (newExpression == null || causeType == null) {
return false;
}
final PsiMethod constructor = newExpression.resolveConstructor();
@@ -145,8 +144,7 @@ public class UnnecessaryInitCauseInspectionBase extends BaseInspection {
}
}
final PsiParameter lastParameter = parameters[parameters.length - 1];
final PsiType type = lastParameter.getType();
if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_THROWABLE)) {
if (lastParameter.getType().isAssignableFrom(causeType)) {
return true;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2017 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -120,6 +120,7 @@ public class TypeUtils {
return false;
}
@Contract("null, _ -> false")
public static boolean expressionHasTypeOrSubtype(@Nullable PsiExpression expression, @NonNls @NotNull String typeName) {
return expressionHasTypeOrSubtype(expression, new String[] {typeName}) != null;
}
@@ -129,8 +130,9 @@ public class TypeUtils {
if (expression == null) {
return null;
}
PsiType type = expression instanceof PsiFunctionalExpression ? ((PsiFunctionalExpression)expression).getFunctionalInterfaceType()
: expression.getType();
final PsiType type = expression instanceof PsiFunctionalExpression
? ((PsiFunctionalExpression)expression).getFunctionalInterfaceType()
: expression.getType();
if (type == null) {
return null;
}
@@ -236,7 +238,7 @@ public class TypeUtils {
}
final PsiClassType classType = (PsiClassType)type;
final PsiClass aClass = classType.resolve();
return aClass != null && aClass instanceof PsiTypeParameter;
return aClass instanceof PsiTypeParameter;
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-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.
@@ -52,6 +52,25 @@ public class UnnecessaryInitCauseInspectionTest extends LightInspectionTestCase
"}");
}
public void testIncompatibleType() {
doTest("import java.io.*;" +
"class X {" +
" void m() throws Exception {" +
" try {" +
" }catch (RuntimeException ex) {" +
" YException wrapper = new YException(\"foo\");" +
" wrapper.initCause(ex);" +
" throw wrapper;" +
" }" +
" }" +
"" +
" class YException extends Exception {" +
" public YException(String msg) { super(msg); }" +
" public YException(String msg, IOException cause) { super(msg, cause); }" +
" }" +
"}");
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {