mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new "Parameter type prevents overriding" inspection
This commit is contained in:
@@ -1018,6 +1018,10 @@
|
||||
bundle="com.siyeh.InspectionGadgetsBundle" key="non.protected.constructor.in.abstract.class.display.name"
|
||||
groupBundle="messages.InspectionsBundle" groupKey="group.names.inheritance.issues" enabledByDefault="false"
|
||||
level="WARNING" implementationClass="com.siyeh.ig.inheritance.NonProtectedConstructorInAbstractClassInspection"/>
|
||||
<localInspection language="JAVA" shortName="ParameterTypePreventsOverriding" bundle="com.siyeh.InspectionGadgetsBundle"
|
||||
key="parameter.type.prevents.overriding.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.inheritance.issues" enabledByDefault="false" level="WARNING"
|
||||
implementationClass="com.siyeh.ig.inheritance.ParameterTypePreventsOverridingInspection"/>
|
||||
<localInspection language="JAVA" shortName="ProblematicVarargsMethodOverride" bundle="com.siyeh.InspectionGadgetsBundle"
|
||||
key="problematic.varargs.method.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.inheritance.issues" enabledByDefault="false" level="WARNING"
|
||||
|
||||
+4
@@ -2121,3 +2121,7 @@ return.of.inner.class.display.name=Return of instance of anonymous, local or inn
|
||||
return.of.anonymous.class.problem.descriptor=Return of instance of anonymous class #loc
|
||||
return.of.local.class.problem.descriptor=Return of instance of local class <code>{0}</code> #loc
|
||||
return.of.inner.class.problem.descriptor=Return of instance of non-static inner class <code>{0}</code> #loc
|
||||
parameter.type.prevents.overriding.display.name=Parameter type prevents overriding
|
||||
parameter.type.prevents.overriding.problem.descriptor=Parameter type <code>#ref</code> is from package ''{0}'' while super method parameter type is from package ''{1}'' preventing overriding
|
||||
parameter.type.prevents.overriding.quickfix=Change type of parameter to ''{0}''
|
||||
parameter.type.prevents.overriding.family.quickfix=Change type of parameter
|
||||
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.siyeh.ig.inheritance;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class ParameterTypePreventsOverridingInspection extends BaseInspection {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message("parameter.type.prevents.overriding.display.name");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String buildErrorString(Object... infos) {
|
||||
final PsiTypeElement typeElement = (PsiTypeElement)infos[0];
|
||||
final PsiType type = typeElement.getType();
|
||||
final String packageName = StringUtil.getPackageName(type.getCanonicalText());
|
||||
final PsiTypeElement superTypeElement = (PsiTypeElement)infos[1];
|
||||
final PsiType superType = superTypeElement.getType();
|
||||
final String superPackageName = StringUtil.getPackageName(superType.getCanonicalText());
|
||||
return InspectionGadgetsBundle.message("parameter.type.prevents.overriding.problem.descriptor", packageName, superPackageName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionGadgetsFix buildFix(Object... infos) {
|
||||
final PsiTypeElement typeElement = (PsiTypeElement)infos[1];
|
||||
final PsiType type = typeElement.getType();
|
||||
return new ParameterTypePreventsOverridingFix(type.getCanonicalText());
|
||||
}
|
||||
|
||||
private static class ParameterTypePreventsOverridingFix extends InspectionGadgetsFix {
|
||||
|
||||
private final String myNewTypeText;
|
||||
|
||||
public ParameterTypePreventsOverridingFix(String newTypeText) {
|
||||
myNewTypeText = newTypeText;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return InspectionGadgetsBundle.message("parameter.type.prevents.overriding.quickfix", myNewTypeText);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionGadgetsBundle.message("parameter.type.prevents.overriding.family.quickfix");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (!(element instanceof PsiTypeElement)) {
|
||||
return;
|
||||
}
|
||||
final PsiTypeElement typeElement = (PsiTypeElement)element;
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(typeElement.getProject());
|
||||
final PsiTypeElement newTypeElement = factory.createTypeElementFromText(myNewTypeText, typeElement);
|
||||
typeElement.replace(newTypeElement);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new ParameterTypePreventsOverridingVisitor();
|
||||
}
|
||||
|
||||
private static class ParameterTypePreventsOverridingVisitor extends BaseInspectionVisitor {
|
||||
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
super.visitMethod(method);
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
final int parameterCount = parameterList.getParametersCount();
|
||||
if (parameterCount == 0) {
|
||||
return;
|
||||
}
|
||||
final PsiType returnType = method.getReturnType();
|
||||
if (returnType == null) {
|
||||
return;
|
||||
}
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) {
|
||||
return;
|
||||
}
|
||||
final PsiClass superClass = containingClass.getSuperClass();
|
||||
if (superClass == null) {
|
||||
return;
|
||||
}
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
final String name = method.getName();
|
||||
final PsiMethod[] superMethods = superClass.findMethodsByName(name, true);
|
||||
outer: for (PsiMethod superMethod : superMethods) {
|
||||
final PsiType superReturnType = superMethod.getReturnType();
|
||||
if (superReturnType == null || !superReturnType.isAssignableFrom(returnType)) {
|
||||
continue;
|
||||
}
|
||||
final PsiParameterList superParameterList = superMethod.getParameterList();
|
||||
if (superParameterList.getParametersCount() != parameterCount) {
|
||||
continue;
|
||||
}
|
||||
final PsiParameter[] superParameters = superParameterList.getParameters();
|
||||
final Map<PsiTypeElement, PsiTypeElement> problemTypeElements = ContainerUtilRt.newHashMap(2);
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
final PsiParameter parameter = parameters[i];
|
||||
final PsiParameter superParameter = superParameters[i];
|
||||
final PsiType type = parameter.getType();
|
||||
final PsiType superType = superParameter.getType();
|
||||
if (type.equals(superType)) {
|
||||
continue;
|
||||
}
|
||||
if (!type.getPresentableText().equals(superType.getPresentableText())) {
|
||||
return;
|
||||
}
|
||||
final PsiTypeElement typeElement = parameter.getTypeElement();
|
||||
if (typeElement == null) {
|
||||
return;
|
||||
}
|
||||
final PsiTypeElement superParameterTypeElement = superParameter.getTypeElement();
|
||||
if (superParameterTypeElement == null) {
|
||||
continue outer;
|
||||
}
|
||||
problemTypeElements.put(typeElement, superParameterTypeElement);
|
||||
}
|
||||
for (Map.Entry<PsiTypeElement, PsiTypeElement> entry : problemTypeElements.entrySet()) {
|
||||
registerError(entry.getKey(), entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports method parameter types in methods that look like they are overriding a super method,
|
||||
but do not because of the parameter type coming from a different package than the super method type,
|
||||
although the class name matches.
|
||||
This prevents the parameter's method from overriding the super method and can be very confusing.
|
||||
<p>Example:
|
||||
<pre><code>
|
||||
<b>public class</b> A {
|
||||
<b>public void</b> method(Object o) {}
|
||||
}
|
||||
|
||||
<b>public class</b> B <b>extends</b> A {
|
||||
<b>public void</b> method(Object o) {} // warning on parameter type here
|
||||
<b>class</b> Object {}
|
||||
}
|
||||
</code></pre>
|
||||
<!-- tooltip end -->
|
||||
<p>
|
||||
<small>New in 14</small>
|
||||
</body>
|
||||
</html>
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.siyeh.ig.inheritance;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class ParameterTypePreventsOverridingInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void testSimple() {
|
||||
doTest("package c;" +
|
||||
"import a.*;" +
|
||||
"import b.String;" +
|
||||
"class Sub extends Super {" +
|
||||
" void m(/*Parameter type 'String' is from package 'b' while super method parameter type is from package 'java.lang' preventing overriding*/String/**/ s) {}" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testNonMatchingReturnType() {
|
||||
doTest("package c;" +
|
||||
"import a.*;" +
|
||||
"import b.String;" +
|
||||
"class Sub extends Super {" +
|
||||
" int m(String s) {" +
|
||||
" return -1;" +
|
||||
" }" +
|
||||
" class String {}" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testMatchingReturnType() {
|
||||
doTest("package c;" +
|
||||
"import a.*;" +
|
||||
"import b.String;" +
|
||||
"class Sub extends Super {" +
|
||||
" Integer n(/*Parameter type 'String' is from package 'b' while super method parameter type is from package 'java.lang' preventing overriding*/String/**/ s, " +
|
||||
" /*Parameter type 'String' is from package 'b' while super method parameter type is from package 'java.lang' preventing overriding*/String/**/ t) {" +
|
||||
" return null;" +
|
||||
" }" +
|
||||
"}");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getEnvironmentClasses() {
|
||||
return new String[]{
|
||||
"package a;" +
|
||||
"public class Super {" +
|
||||
" void m(String s) {}" +
|
||||
" Object n(String s, String t) {" +
|
||||
" return null;" +
|
||||
" }" +
|
||||
"}",
|
||||
"package b;" +
|
||||
"public class String {}"
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new ParameterTypePreventsOverridingInspection();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user