cleanup IDEA-382376: move com.siyeh.ig.inheritance package from java-impl to java-impl-inspections

GitOrigin-RevId: 6ac8e5a9c13fcb5f26d8719020affcaf064bd429
This commit is contained in:
Bartek Pacia
2026-02-12 12:49:55 +00:00
committed by intellij-monorepo-bot
parent 2a72828cba
commit c4f9ba47d3
4 changed files with 0 additions and 0 deletions
@@ -0,0 +1,100 @@
/*
* Copyright 2003-2011 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.
* 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.LocalQuickFix;
import com.intellij.psi.PsiAnonymousClass;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiParameterList;
import com.intellij.psi.PsiTypes;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.fixes.ReplaceInheritanceWithDelegationFix;
import com.siyeh.ig.psiutils.CollectionUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
public final class ExtendsConcreteCollectionInspection extends BaseInspection {
@Override
protected LocalQuickFix buildFix(Object... infos) {
final PsiClass aClass = (PsiClass)infos[1];
// skip inheritance with delegation for anonymous classes
// or better suggest to replace anonymous with inner and then replace with delegation
if (aClass instanceof PsiAnonymousClass) {
return null;
}
return new ReplaceInheritanceWithDelegationFix();
}
@Override
public @NotNull String getID() {
return "ClassExtendsConcreteCollection";
}
@Override
public @NotNull String buildErrorString(Object... infos) {
final PsiClass superClass = (PsiClass)infos[0];
final PsiClass aClass = (PsiClass)infos[1];
if (aClass instanceof PsiAnonymousClass) {
return InspectionGadgetsBundle.message("anonymous.extends.concrete.collection.problem.descriptor", superClass.getQualifiedName());
} else {
return InspectionGadgetsBundle.message("extends.concrete.collection.problem.descriptor", superClass.getQualifiedName());
}
}
@Override
public @NotNull BaseInspectionVisitor buildVisitor() {
return new ExtendsConcreteCollectionVisitor();
}
private static class ExtendsConcreteCollectionVisitor extends BaseInspectionVisitor {
@Override
public void visitClass(@NotNull PsiClass aClass) {
if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) {
return;
}
final PsiClass superClass = aClass.getSuperClass();
if (!CollectionUtils.isConcreteCollectionClass(superClass)) {
return;
}
final String qualifiedName = superClass.getQualifiedName();
if ("java.util.LinkedHashMap".equals(qualifiedName)) {
final PsiMethod[] methods = aClass.findMethodsByName("removeEldestEntry", false);
final PsiClassType entryType = TypeUtils.getType("java.util.Map.Entry", aClass);
for (PsiMethod method : methods) {
if (!PsiTypes.booleanType().equals(method.getReturnType())) {
continue;
}
final PsiParameterList parameterList = method.getParameterList();
if ( parameterList.getParametersCount() != 1) {
continue;
}
final PsiParameter parameter = parameterList.getParameters()[0];
if (entryType.isAssignableFrom(parameter.getType())) {
return;
}
}
}
registerClassError(aClass, superClass, aClass);
}
}
}
@@ -0,0 +1,79 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.inheritance;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.options.JavaClassValidator;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.codeInspection.util.SpecialAnnotationsUtilBase;
import com.intellij.psi.PsiClass;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.InheritanceUtil;
import com.siyeh.ig.ui.ExternalizableStringSet;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
import static com.intellij.codeInspection.options.OptPane.stringList;
public final class InterfaceNeverImplementedInspection extends BaseInspection {
@SuppressWarnings("PublicField")
public boolean ignoreInterfacesThatOnlyDeclareConstants = false;
@SuppressWarnings("PublicField")
public final ExternalizableStringSet ignorableAnnotations = new ExternalizableStringSet();
@Override
public void writeSettings(@NotNull Element node) {
defaultWriteSettings(node, "ignorableAnnotations");
ignorableAnnotations.writeSettings(node, "ignorableAnnotations");
}
@Override
protected LocalQuickFix @NotNull [] buildFixes(Object... infos) {
final PsiClass aClass = (PsiClass)infos[0];
return SpecialAnnotationsUtilBase.createAddAnnotationToListFixes(aClass, this, insp -> insp.ignorableAnnotations)
.toArray(LocalQuickFix.EMPTY_ARRAY);
}
@Override
public @NotNull OptPane getOptionsPane() {
return pane(
stringList("ignorableAnnotations", InspectionGadgetsBundle.message("ignore.if.annotated.by"),
new JavaClassValidator().annotationsOnly()),
checkbox("ignoreInterfacesThatOnlyDeclareConstants", InspectionGadgetsBundle.message("interface.never.implemented.option"))
);
}
@Override
protected @NotNull String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"interface.never.implemented.problem.descriptor");
}
@Override
public @NotNull BaseInspectionVisitor buildVisitor() {
return new InterfaceNeverImplementedVisitor();
}
private class InterfaceNeverImplementedVisitor extends BaseInspectionVisitor {
@Override
public void visitClass(@NotNull PsiClass aClass) {
if (!aClass.isInterface() || aClass.isAnnotationType()) {
return;
}
if (ignoreInterfacesThatOnlyDeclareConstants && aClass.getMethods().length == 0 && aClass.getFields().length != 0) {
return;
}
if (AnnotationUtil.isAnnotated(aClass, ignorableAnnotations, 0) || InheritanceUtil.hasImplementation(aClass)) {
return;
}
registerClassError(aClass, aClass);
}
}
}
@@ -0,0 +1,251 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.inheritance;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.codeInspection.AnnotateMethodFix;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.openapi.module.JdkApiCompatibilityService;
import com.intellij.openapi.module.LanguageLevelUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.impl.scopes.ModulesScope;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootModificationTracker;
import com.intellij.pom.java.JavaFeature;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiAnonymousClass;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.JavaPsiRecordUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ConcurrentFactoryMap;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.JavaOverridingMethodUtil;
import com.siyeh.ig.psiutils.MethodUtils;
import one.util.streamex.StreamEx;
import org.jdom.Element;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
public class MissingOverrideAnnotationInspection extends BaseInspection implements CleanupLocalInspectionTool{
@SuppressWarnings("PublicField")
public boolean ignoreObjectMethods = true;
@SuppressWarnings("PublicField")
public boolean ignoreAnonymousClassMethods;
public boolean warnInSuper = true;
@Override
public void writeSettings(@NotNull Element node) {
defaultWriteSettings(node, "warnInSuper");
writeBooleanOption(node, "warnInSuper", true);
}
@Override
public @NotNull String getID() {
return "override";
}
@Override
protected LocalQuickFix buildFix(Object... infos) {
final boolean annotateMethod = (boolean)infos[0];
final boolean annotateHierarchy = (boolean)infos[1];
return createAnnotateFix(annotateMethod, annotateHierarchy);
}
@Override
protected @NotNull String buildErrorString(Object... infos) {
final boolean annotateMethod = (boolean)infos[0];
return InspectionGadgetsBundle.message(annotateMethod
? "missing.override.annotation.problem.descriptor"
: "missing.override.annotation.in.overriding.problem.descriptor");
}
@Override
public @NotNull OptPane getOptionsPane() {
return pane(
checkbox("ignoreObjectMethods", InspectionGadgetsBundle.message("ignore.equals.hashcode.and.tostring")),
checkbox("ignoreAnonymousClassMethods", InspectionGadgetsBundle.message("ignore.methods.in.anonymous.classes")),
checkbox("warnInSuper", InspectionGadgetsBundle.message("missing.override.warn.on.super.option")));
}
@Override
public @NotNull Set<@NotNull JavaFeature> requiredFeatures() {
return Set.of(JavaFeature.ANNOTATIONS);
}
@Override
public @NotNull BaseInspectionVisitor buildVisitor() {
return new MissingOverrideAnnotationVisitor();
}
private class MissingOverrideAnnotationVisitor extends BaseInspectionVisitor {
@Override
public void visitMethod(@NotNull PsiMethod method) {
if (method.getNameIdentifier() == null || method.isConstructor()) {
return;
}
if (method.hasModifierProperty(PsiModifier.PRIVATE) || method.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
final PsiClass methodClass = method.getContainingClass();
if (methodClass == null) {
return;
}
if (ignoreObjectMethods &&
(MethodUtils.isHashCode(method) || MethodUtils.isEquals(method) || MethodUtils.isToString(method))) {
return;
}
final boolean annotateMethod = isMissingOverride(method);
final boolean annotateHierarchy = warnInSuper && isMissingOverrideInOverriders(method);
if (annotateMethod || annotateHierarchy) {
registerMethodError(method, annotateMethod, annotateHierarchy);
}
}
// we assume:
// 1) method name is not frequently used
// 2) most of overridden methods already have @Override annotation
// 3) only one annotation with short name 'Override' exists: it's 'java.lang.Override'
private static boolean isMissingOverrideInOverriders(@NotNull PsiMethod method) {
if (!PsiUtil.canBeOverridden(method)) return false;
Project project = method.getProject();
final boolean isInterface = Objects.requireNonNull(method.getContainingClass()).isInterface();
JavaFeature requiredFeature = isInterface ? JavaFeature.OVERRIDE_INTERFACE : JavaFeature.ANNOTATIONS;
GlobalSearchScope scope = getLanguageLevelScope(requiredFeature.getMinimumLevel(), project);
if (scope == null) return false;
int paramCount = method.getParameterList().getParametersCount();
Predicate<PsiMethod> preFilter = m -> m.getParameterList().getParametersCount() == paramCount &&
!JavaOverridingMethodUtil.containsAnnotationWithName(m, "Override");
Stream<PsiMethod> overridingMethods = JavaOverridingMethodUtil.getOverridingMethodsIfCheapEnough(method, scope, preFilter);
return overridingMethods != null && overridingMethods.findAny().isPresent();
}
private boolean isMissingOverride(@NotNull PsiMethod method) {
PsiClass methodClass = method.getContainingClass();
if (ignoreAnonymousClassMethods && methodClass instanceof PsiAnonymousClass) {
return false;
}
if (hasOverrideAnnotation(method)) {
return false;
}
LanguageLevel level = PsiUtil.getLanguageLevel(method);
if (JavaPsiRecordUtil.getRecordComponentForAccessor(method) != null) {
return true;
}
if (JavaFeature.OVERRIDE_INTERFACE.isSufficient(level)) {
if (!isJdk6Override(method, methodClass)) {
return false;
}
}
else if (!isJdk5Override(method, methodClass)) {
return false;
}
return true;
}
private static boolean hasOverrideAnnotation(PsiModifierListOwner modifierListOwner) {
final PsiModifierList modifierList = modifierListOwner.getModifierList();
if (modifierList != null && modifierList.hasAnnotation(CommonClassNames.JAVA_LANG_OVERRIDE)) {
return true;
}
final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(modifierListOwner.getProject());
final List<PsiAnnotation> annotations =
annotationsManager.findExternalAnnotations(modifierListOwner, CommonClassNames.JAVA_LANG_OVERRIDE);
return !annotations.isEmpty();
}
private static boolean isJdk6Override(PsiMethod method, PsiClass methodClass) {
final PsiMethod[] superMethods = method.findSuperMethods();
boolean hasSupers = false;
for (PsiMethod superMethod : superMethods) {
final PsiClass superClass = superMethod.getContainingClass();
if (ignoreSuperMethod(method, methodClass, superMethod, superClass)) {
continue;
}
hasSupers = true;
if (!superMethod.hasModifierProperty(PsiModifier.PROTECTED)) {
return true;
}
}
// is override except if this is an interface method
// overriding a protected method in java.lang.Object
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6501053
return hasSupers && !methodClass.isInterface();
}
private static boolean isJdk5Override(PsiMethod method, PsiClass methodClass) {
final PsiMethod[] superMethods = method.findSuperMethods();
for (PsiMethod superMethod : superMethods) {
final PsiClass superClass = superMethod.getContainingClass();
if (ignoreSuperMethod(method, methodClass, superMethod, superClass)) {
continue;
}
if (superClass.isInterface()) {
continue;
}
if (methodClass.isInterface() &&
superMethod.hasModifierProperty(PsiModifier.PROTECTED)) {
// only true for J2SE java.lang.Object.clone(), but might
// be different on other/newer java platforms
continue;
}
return true;
}
return false;
}
@Contract("_, _, _,null -> true")
private static boolean ignoreSuperMethod(PsiMethod method, PsiClass methodClass, PsiMethod superMethod, PsiClass superClass) {
return !InheritanceUtil.isInheritorOrSelf(methodClass, superClass, true) ||
JdkApiCompatibilityService.getInstance().firstCompatibleLanguageLevel(superMethod, PsiUtil.getLanguageLevel(method)) != null;
}
}
private static @NotNull LocalQuickFix createAnnotateFix(boolean annotateMethod, boolean annotateHierarchy) {
return new AnnotateMethodFix(CommonClassNames.JAVA_LANG_OVERRIDE, annotateHierarchy, annotateMethod);
}
private static @Nullable GlobalSearchScope getLanguageLevelScope(@NotNull LanguageLevel _minimal, @NotNull Project project) {
Map<LanguageLevel, GlobalSearchScope> map = CachedValuesManager.getManager(project).getCachedValue(project, () -> {
Map<LanguageLevel, GlobalSearchScope> result = ConcurrentFactoryMap.createMap(minimal -> {
Set<Module> modules = StreamEx
.of(ModuleManager.getInstance(project).getModules())
.filter(m -> LanguageLevelUtil.getEffectiveLanguageLevel(m).isAtLeast(minimal))
.toSet();
return modules == null ? null : new ModulesScope(modules, project);
});
return CachedValueProvider.Result.create(result, ProjectRootModificationTracker.getInstance(project));
});
return map.get(_minimal);
}
}
@@ -0,0 +1,254 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.inheritance;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.options.JavaClassValidator;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
import com.intellij.openapi.project.Project;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiCodeBlock;
import com.intellij.psi.PsiDeclarationStatement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiJavaToken;
import com.intellij.psi.PsiLocalVariable;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiStatement;
import com.intellij.psi.PsiThrowStatement;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypes;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.util.AstLoadingFilter;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.CloneUtils;
import com.siyeh.ig.psiutils.ControlFlowUtils;
import com.siyeh.ig.psiutils.MethodCallUtils;
import com.siyeh.ig.psiutils.MethodUtils;
import com.siyeh.ig.psiutils.VariableNameGenerator;
import com.siyeh.ig.ui.ExternalizableStringSet;
import org.jdom.Element;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
import static com.intellij.codeInspection.options.OptPane.stringList;
/**
* @author Bas Leijdekkers
*/
public final class RefusedBequestInspection extends BaseInspection {
@SuppressWarnings("PublicField") public final ExternalizableStringSet annotations =
new ExternalizableStringSet("javax.annotation.OverridingMethodsMustInvokeSuper",
"org.jetbrains.annotations.MustBeInvokedByOverriders");
@SuppressWarnings("PublicField") public boolean ignoreEmptySuperMethods;
@SuppressWarnings("PublicField") public boolean ignoreDefaultSuperMethods;
@SuppressWarnings("PublicField") public boolean onlyReportWhenAnnotated = true;
@Override
public @NotNull OptPane getOptionsPane() {
return pane(
checkbox("onlyReportWhenAnnotated", InspectionGadgetsBundle.message("inspection.refused.bequest.super.annotated.option"),
stringList("annotations", "", new JavaClassValidator().annotationsOnly())),
checkbox("ignoreEmptySuperMethods", InspectionGadgetsBundle.message("refused.bequest.ignore.empty.super.methods.option")),
checkbox("ignoreDefaultSuperMethods", InspectionGadgetsBundle.message("refused.bequest.ignore.default.super.methods.option"))
);
}
@Override
protected @Nullable LocalQuickFix buildFix(Object... infos) {
return new RefusedBequestFix();
}
@Override
public @NotNull String getID() {
return "MethodDoesntCallSuperMethod";
}
@Override
public void writeSettings(@NotNull Element node) {
defaultWriteSettings(node, "onlyReportWhenAnnotated", "annotations", "ignoreDefaultSuperMethods");
writeBooleanOption(node, "onlyReportWhenAnnotated", false);
writeBooleanOption(node, "ignoreDefaultSuperMethods", false);
annotations.writeSettings(node, "annotations");
}
@Override
public void readSettings(@NotNull Element node) {
onlyReportWhenAnnotated = false; // should be false when not present, used to be false by default in the past.
super.readSettings(node);
}
@Override
public @NotNull String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message("refused.bequest.problem.descriptor");
}
@Override
public @NotNull BaseInspectionVisitor buildVisitor() {
return new RefusedBequestVisitor();
}
private static class RefusedBequestFix extends PsiUpdateModCommandQuickFix {
@Override
public @Nls @NotNull String getFamilyName() {
return InspectionGadgetsBundle.message("refused.bequest.fix.family.name");
}
@Override
protected void applyFix(@NotNull Project project, @NotNull PsiElement methodName, @NotNull ModPsiUpdater updater) {
final PsiMethod method = (PsiMethod)methodName.getParent();
assert method != null;
final PsiCodeBlock body = method.getBody();
if (body == null) {
return;
}
final PsiType returnType = method.getReturnType();
final @NonNls StringBuilder statementText = new StringBuilder();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
if (returnType != null && !PsiTypes.voidType().equals(returnType)) {
if (JavaCodeStyleSettings.getInstance(method.getContainingFile()).GENERATE_FINAL_LOCALS) {
statementText.append("final ");
}
statementText.append(returnType.getCanonicalText()).append(' ');
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
final SuggestedNameInfo baseNameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, returnType);
final SuggestedNameInfo nameInfo = codeStyleManager.suggestUniqueVariableName(baseNameInfo, body, true);
statementText.append(nameInfo.names.length > 0 ? nameInfo.names[0] : "result");
statementText.append('=');
final MethodSignatureBackedByPsiMethod superMethodSignature = MethodUtils.getSuperMethodSignature(method);
if (superMethodSignature == null) {
return;
}
final PsiMethod superMethod = superMethodSignature.getMethod();
final PsiType superReturnType = superMethod.getReturnType();
final PsiType substitutedType = superMethodSignature.getSubstitutor().substitute(superReturnType);
if (superReturnType != null && !returnType.isAssignableFrom(substitutedType)) {
statementText.append('(').append(returnType.getCanonicalText()).append(')');
}
}
statementText.append("super.").append(methodName.getText()).append('(');
boolean comma = false;
for (PsiParameter parameter : method.getParameterList().getParameters()) {
if (comma) statementText.append(',');
else comma = true;
statementText.append(parameter.getName());
}
statementText.append(");");
final PsiStatement newStatement = factory.createStatementFromText(statementText.toString(), null);
final CodeStyleManager styleManager = CodeStyleManager.getInstance(project);
final PsiJavaToken brace = body.getLBrace();
final PsiElement element = body.addAfter(newStatement, brace);
final PsiElement element1 = styleManager.reformat(element);
final PsiElement element2 = JavaCodeStyleManager.getInstance(project).shortenClassReferences(element1);
updater.highlight(element2);
if (element2 instanceof PsiDeclarationStatement declarationStatement) {
final PsiLocalVariable variable = (PsiLocalVariable)declarationStatement.getDeclaredElements()[0];
List<String> nameSuggestions = new VariableNameGenerator(variable, VariableKind.LOCAL_VARIABLE)
.byExpression(variable.getInitializer())
.byType(variable.getType())
.byName("original", "superResult")
.generateAll(true);
updater.rename(variable, nameSuggestions);
}
}
}
private class RefusedBequestVisitor extends BaseInspectionVisitor {
@Override
public void visitMethod(@NotNull PsiMethod method) {
super.visitMethod(method);
final PsiCodeBlock body = method.getBody();
if (body == null) {
return;
}
if (method.getNameIdentifier() == null) {
return;
}
final PsiMethod superMethod = getDirectSuperMethod(method);
if (superMethod == null) {
return;
}
final String methodName = method.getName();
if (!HardcodedMethodConstants.CLONE.equals(methodName)) {
final PsiClass superClass = superMethod.getContainingClass();
if (superClass != null) {
final String superClassName = superClass.getQualifiedName();
if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClassName)) {
return;
}
}
}
if (ignoreEmptySuperMethods && isTrivial(superMethod)) {
return;
}
final boolean isClone = CloneUtils.isClone(method);
if (onlyReportWhenAnnotated && !AnnotationUtil.isAnnotated(superMethod, annotations, 0)) {
if (!isClone && !isJUnitSetUpOrTearDown(method) && !MethodUtils.isFinalize(method) || isTrivial(superMethod)) {
return;
}
}
if (isClone && ClassUtils.isSingleton(method.getContainingClass())) {
return;
}
if (MethodCallUtils.containsSuperMethodCall(method) || ControlFlowUtils.methodAlwaysThrowsException(method)) {
return;
}
registerMethodError(method);
}
private static boolean isTrivial(PsiMethod method) {
final PsiElement element = method.getNavigationElement();
return AstLoadingFilter.forceAllowTreeLoading(method.getContainingFile(),
() -> MethodUtils.isTrivial(element instanceof PsiMethod
? (PsiMethod)element
: method, s -> s instanceof PsiThrowStatement));
}
private static boolean isJUnitSetUpOrTearDown(PsiMethod method) {
final String name = method.getName();
if (!"setUp".equals(name) && !"tearDown".equals(name)) {
return false;
}
if (!method.getParameterList().isEmpty()) {
return false;
}
final PsiClass aClass = method.getContainingClass();
return InheritanceUtil.isInheritor(aClass, "junit.framework.TestCase");
}
private @Nullable PsiMethod getDirectSuperMethod(PsiMethod method) {
final PsiMethod superMethod = MethodUtils.getSuper(method);
if (superMethod == null ||
superMethod.hasModifierProperty(PsiModifier.ABSTRACT) ||
ignoreDefaultSuperMethods && superMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
return null;
}
return superMethod;
}
}
}