mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-91960 (Type parameter extends final class inspection warns on cases when can not be removed)
This commit is contained in:
+54
-14
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2012 Bas Leijdekkers
|
||||
* Copyright 2006-2013 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,11 +15,13 @@
|
||||
*/
|
||||
package com.siyeh.ig.inheritance;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
@@ -127,10 +129,7 @@ public class TypeParameterExtendsFinalClassInspection extends BaseInspection {
|
||||
}
|
||||
final PsiClassType extendsType = extendsListTypes[0];
|
||||
final PsiClass aClass = extendsType.resolve();
|
||||
if (aClass == null) {
|
||||
return;
|
||||
}
|
||||
if (!aClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
if (aClass == null || !aClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
return;
|
||||
}
|
||||
final PsiIdentifier nameIdentifier = classParameter.getNameIdentifier();
|
||||
@@ -156,22 +155,63 @@ public class TypeParameterExtendsFinalClassInspection extends BaseInspection {
|
||||
if (aClass == null || !aClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
return;
|
||||
}
|
||||
if (isPartOfOverriddenMethod(typeElement)) {
|
||||
if (!shouldReport(typeElement)) {
|
||||
return;
|
||||
}
|
||||
registerError(typeElement.getFirstChild(), aClass, Integer.valueOf(2));
|
||||
}
|
||||
|
||||
private static boolean isPartOfOverriddenMethod(PsiTypeElement typeElement) {
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(typeElement, PsiMethod.class);
|
||||
if (method == null) {
|
||||
return false;
|
||||
private static boolean shouldReport(PsiTypeElement typeElement) {
|
||||
final PsiElement ancestor = PsiTreeUtil.skipParentsOfType(
|
||||
typeElement, PsiTypeElement.class, PsiJavaCodeReferenceElement.class, PsiReferenceParameterList.class);
|
||||
if (ancestor instanceof PsiParameter) {
|
||||
final PsiParameter parameter = (PsiParameter)ancestor;
|
||||
final PsiElement scope = parameter.getDeclarationScope();
|
||||
if (scope instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)scope;
|
||||
if (MethodUtils.hasSuper(method)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (scope instanceof PsiForeachStatement) {
|
||||
final PsiForeachStatement foreachStatement = (PsiForeachStatement)scope;
|
||||
final PsiParameter iterationParameter = foreachStatement.getIterationParameter();
|
||||
final PsiType iterationType = iterationParameter.getType();
|
||||
final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
|
||||
if (iteratedValue == null) {
|
||||
return false; // incomplete code
|
||||
}
|
||||
final PsiType type = JavaGenericsUtil.getCollectionItemType(iteratedValue);
|
||||
if (type == null || !TypeConversionUtil.isAssignable(iterationType, type)) { // sanity check
|
||||
return false;
|
||||
}
|
||||
if (type.equals(iterationType)) {
|
||||
return false;
|
||||
}
|
||||
if (!(type instanceof PsiCapturedWildcardType)) {
|
||||
return true;
|
||||
}
|
||||
final PsiCapturedWildcardType capturedWildcardType = (PsiCapturedWildcardType)type;
|
||||
final PsiType upperBound = capturedWildcardType.getUpperBound();
|
||||
if (iterationType.equals(upperBound)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (PsiTreeUtil.isAncestor(body, typeElement, true)) {
|
||||
return false;
|
||||
else if (ancestor instanceof PsiLocalVariable) {
|
||||
final PsiLocalVariable localVariable = (PsiLocalVariable)ancestor;
|
||||
final PsiExpression initializer = localVariable.getInitializer();
|
||||
if (initializer == null) {
|
||||
return true;
|
||||
}
|
||||
final PsiType type = initializer.getType();
|
||||
final PsiType expectedType = GenericsUtil.getVariableTypeByExpressionType(type);
|
||||
final PsiType variableType = localVariable.getType();
|
||||
if (variableType.equals(expectedType)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return MethodUtils.hasSuper(method);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-2
@@ -1,7 +1,7 @@
|
||||
package com.siyeh.igtest.inheritance.type_parameter_extends_final_class;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class TypeParameterExtendsFinalClass<T extends String> {}
|
||||
final class Usee {}
|
||||
@@ -15,4 +15,12 @@ abstract class MyList implements List<Integer> {
|
||||
public boolean addAll(Collection<? extends Integer> c) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
abstract class SampleMap<T extends String> implements Map<String, Object> {
|
||||
|
||||
public void putAll(final Map<? extends String, ?> m) {
|
||||
final Set<? extends Entry<? extends String,?>> entries = m.entrySet();
|
||||
for (Entry<? extends String, ?> entry : entries) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -13,4 +13,11 @@
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Type parameter extends final class</problem_class>
|
||||
<description>Wildcard type argument <code>?</code> extends final class 'Usee' #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>TypeParameterExtendsFinalClass.java</file>
|
||||
<line>19</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Type parameter extends final class</problem_class>
|
||||
<description>Type parameter <code>T</code> extends 'final' class 'String' #loc</description>
|
||||
</problem>
|
||||
</problems>
|
||||
Reference in New Issue
Block a user