mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
redundant throws inspection:
1. global and local inspections are merged to one 2. local inspection reports "non-final" methods (if cheap enough) IDEA-177230
This commit is contained in:
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
@@ -49,7 +50,7 @@ public class MethodThrowsFix extends LocalQuickFixOnPsiElement {
|
||||
@Override
|
||||
public String getText() {
|
||||
return QuickFixBundle.message(myShouldThrow ? "fix.throws.list.add.exception" : "fix.throws.list.remove.exception",
|
||||
myThrowsCanonicalText,
|
||||
StringUtil.getShortName(myThrowsCanonicalText),
|
||||
myMethodName);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MethodThrowsFix;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class DeleteThrowsFix implements LocalQuickFix {
|
||||
private final MethodThrowsFix myQuickFix;
|
||||
|
||||
public DeleteThrowsFix(@NotNull PsiMethod method, PsiClassType exceptionClass) {
|
||||
myQuickFix = new MethodThrowsFix(method, exceptionClass, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return myQuickFix.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("fix.throws.list.family");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement element = descriptor.getPsiElement();
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
|
||||
if (method == null) return;
|
||||
final PsiFile psiFile = method.getContainingFile();
|
||||
if (myQuickFix.isAvailable(project, psiFile, method, method)) {
|
||||
myQuickFix.invoke(project, psiFile, method, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -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.
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.codeInspection.duplicateThrows;
|
||||
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MethodThrowsFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
|
||||
import com.intellij.psi.*;
|
||||
@@ -82,7 +83,7 @@ public class DuplicateThrowsInspection extends BaseJavaBatchLocalInspectionTool
|
||||
}
|
||||
}
|
||||
if (problem != null) {
|
||||
holder.registerProblem(ref, problem, ProblemHighlightType.LIKE_UNUSED_SYMBOL, new DeleteThrowsFix(method, type));
|
||||
holder.registerProblem(ref, problem, ProblemHighlightType.LIKE_UNUSED_SYMBOL, new MethodThrowsFix(method, type, false, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.intellij.codeInspection.unneededThrows;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author anna
|
||||
* @since 15-Nov-2005
|
||||
*/
|
||||
public class RedundantThrowsDeclaration extends BaseJavaBatchLocalInspectionTool implements CleanupLocalInspectionTool {
|
||||
@Override
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.DECLARATION_REDUNDANCY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return InspectionsBundle.message("redundant.throws.declaration");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getShortName() {
|
||||
return "RedundantThrowsDeclaration";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull final InspectionManager manager, final boolean isOnTheFly) {
|
||||
final Set<ProblemDescriptor> problems = new HashSet<>();
|
||||
file.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
final ProblemDescriptor descriptor = checkExceptionsNeverThrown(reference, manager, isOnTheFly);
|
||||
if (descriptor != null) {
|
||||
problems.add(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
return problems.isEmpty() ? null : problems.toArray(new ProblemDescriptor[problems.size()]);
|
||||
}
|
||||
|
||||
private static ProblemDescriptor checkExceptionsNeverThrown(PsiJavaCodeReferenceElement referenceElement,
|
||||
InspectionManager inspectionManager,
|
||||
boolean onTheFly) {
|
||||
if (!(referenceElement.getParent() instanceof PsiReferenceList)) return null;
|
||||
PsiReferenceList referenceList = (PsiReferenceList)referenceElement.getParent();
|
||||
if (!(referenceList.getParent() instanceof PsiMethod)) return null;
|
||||
PsiMethod method = (PsiMethod)referenceList.getParent();
|
||||
if (referenceList != method.getThrowsList()) return null;
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) return null;
|
||||
|
||||
PsiManager manager = referenceElement.getManager();
|
||||
PsiClassType exceptionType = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(referenceElement);
|
||||
if (ExceptionUtil.isUncheckedExceptionOrSuperclass(exceptionType)) return null;
|
||||
|
||||
PsiCodeBlock body = method.getBody();
|
||||
if (body == null) return null;
|
||||
|
||||
PsiModifierList modifierList = method.getModifierList();
|
||||
if (!modifierList.hasModifierProperty(PsiModifier.PRIVATE)
|
||||
&& !modifierList.hasModifierProperty(PsiModifier.STATIC)
|
||||
&& !modifierList.hasModifierProperty(PsiModifier.FINAL)
|
||||
&& !method.isConstructor()
|
||||
&& !(containingClass instanceof PsiAnonymousClass)
|
||||
&& !containingClass.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Collection<PsiClassType> types = ExceptionUtil.collectUnhandledExceptions(body, method, false);
|
||||
Collection<PsiClassType> unhandled = new HashSet<>(types);
|
||||
if (method.isConstructor()) {
|
||||
// there may be field initializer throwing exception
|
||||
// that exception must be caught in the constructor
|
||||
PsiField[] fields = containingClass.getFields();
|
||||
for (final PsiField field : fields) {
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC)) continue;
|
||||
PsiExpression initializer = field.getInitializer();
|
||||
if (initializer == null) continue;
|
||||
unhandled.addAll(ExceptionUtil.collectUnhandledExceptions(initializer, field));
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiClassType unhandledException : unhandled) {
|
||||
if (unhandledException.isAssignableFrom(exceptionType) || exceptionType.isAssignableFrom(unhandledException)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (JavaHighlightUtil.isSerializationRelatedMethod(method, containingClass)) return null;
|
||||
|
||||
String description = JavaErrorMessages.message("exception.is.never.thrown", JavaHighlightUtil.formatType(exceptionType));
|
||||
LocalQuickFix quickFixes = new DeleteThrowsFix(method, exceptionType);
|
||||
return inspectionManager.createProblemDescriptor(referenceElement, description, quickFixes, ProblemHighlightType.LIKE_UNUSED_SYMBOL, onTheFly);
|
||||
}
|
||||
}
|
||||
+18
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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,7 +18,6 @@ package com.intellij.codeInspection.unneededThrows;
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.reference.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -31,7 +30,7 @@ import com.intellij.psi.search.searches.AllOverridingMethodsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -41,10 +40,17 @@ import java.util.List;
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class RedundantThrows extends GlobalJavaBatchInspectionTool {
|
||||
public class RedundantThrowsDeclarationInspection extends GlobalJavaBatchInspectionTool {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.unneededThrows.RedundantThrows");
|
||||
private static final String DISPLAY_NAME = InspectionsBundle.message("inspection.redundant.throws.display.name");
|
||||
@NonNls private static final String SHORT_NAME = "RedundantThrows";
|
||||
|
||||
private final RedundantThrowsDeclarationLocalInspection myLocalInspection = new RedundantThrowsDeclarationLocalInspection(this);
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return InspectionsBundle.message("inspection.redundant.throws.display.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@@ -143,24 +149,6 @@ public class RedundantThrows extends GlobalJavaBatchInspectionTool {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return DISPLAY_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.DECLARATION_REDUNDANCY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return SHORT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public QuickFix getQuickFix(String hint) {
|
||||
@@ -287,4 +275,10 @@ public class RedundantThrows extends GlobalJavaBatchInspectionTool {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public LocalInspectionTool getSharedLocalInspectionTool() {
|
||||
return myLocalInspection;
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.intellij.codeInspection.unneededThrows;
|
||||
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.MethodThrowsFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.siyeh.ig.JavaOverridingMethodUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author anna
|
||||
* @since 15-Nov-2005
|
||||
*/
|
||||
public class RedundantThrowsDeclarationLocalInspection extends BaseJavaBatchLocalInspectionTool implements CleanupLocalInspectionTool {
|
||||
private final RedundantThrowsDeclarationInspection myGlobalTool;
|
||||
|
||||
@TestOnly
|
||||
public RedundantThrowsDeclarationLocalInspection() {this(new RedundantThrowsDeclarationInspection());}
|
||||
|
||||
public RedundantThrowsDeclarationLocalInspection(@NotNull RedundantThrowsDeclarationInspection tool) {myGlobalTool = tool;}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
return myGlobalTool.getGroupDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return myGlobalTool.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return myGlobalTool.getShortName();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
return checkExceptionsNeverThrown(method, manager);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ProblemDescriptor[] checkExceptionsNeverThrown(PsiMethod method,
|
||||
InspectionManager inspectionManager) {
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null || JavaHighlightUtil.isSerializationRelatedMethod(method, containingClass)) return null;
|
||||
|
||||
PsiCodeBlock body = method.getBody();
|
||||
if (body == null) return null;
|
||||
|
||||
ReferenceAndType[] thrownExceptions = getThrownCheckedExceptions(method);
|
||||
if (thrownExceptions.length == 0) return null;
|
||||
|
||||
PsiModifierList modifierList = method.getModifierList();
|
||||
boolean needCheckOverridingMethods = !(modifierList.hasModifierProperty(PsiModifier.PRIVATE) ||
|
||||
modifierList.hasModifierProperty(PsiModifier.STATIC) ||
|
||||
modifierList.hasModifierProperty(PsiModifier.FINAL) ||
|
||||
method.isConstructor() ||
|
||||
containingClass instanceof PsiAnonymousClass ||
|
||||
containingClass.hasModifierProperty(PsiModifier.FINAL));
|
||||
Collection<PsiClassType> types = ExceptionUtil.collectUnhandledExceptions(body, method, false);
|
||||
Collection<PsiClassType> unhandled = new HashSet<>(types);
|
||||
if (method.isConstructor()) {
|
||||
// there may be field initializer throwing exception
|
||||
// that exception must be caught in the constructor
|
||||
PsiField[] fields = containingClass.getFields();
|
||||
for (final PsiField field : fields) {
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC)) continue;
|
||||
PsiExpression initializer = field.getInitializer();
|
||||
if (initializer == null) continue;
|
||||
unhandled.addAll(ExceptionUtil.collectUnhandledExceptions(initializer, field));
|
||||
}
|
||||
}
|
||||
|
||||
List<ReferenceAndType> candidates = Arrays.stream(thrownExceptions)
|
||||
.filter(refAndType -> unhandled.stream().noneMatch(unhandledException -> unhandledException.isAssignableFrom(refAndType.type) || refAndType.type.isAssignableFrom(unhandledException)))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (candidates.isEmpty()) return null;
|
||||
if (needCheckOverridingMethods) {
|
||||
|
||||
Set<String> thrownExceptionShortNames = candidates.stream().map(refAndType -> refAndType.type.getClassName()).collect(Collectors.toSet());
|
||||
Predicate<PsiMethod> methodContainsThrownExceptions = m -> Arrays.stream(m.getThrowsList().getReferencedTypes())
|
||||
.map(PsiClassType::getClassName)
|
||||
.anyMatch(thrownExceptionShortNames::contains);
|
||||
Stream<PsiMethod> overridingMethods = JavaOverridingMethodUtil.getOverridingMethodsIfCheapEnough(method, null, methodContainsThrownExceptions);
|
||||
if (overridingMethods == null) return null;
|
||||
|
||||
Iterator<PsiMethod> overridingMethodIt = overridingMethods.iterator();
|
||||
while (overridingMethodIt.hasNext()) {
|
||||
PsiMethod m = overridingMethodIt.next();
|
||||
PsiClassType[] overridingMethodThrownException = m.getThrowsList().getReferencedTypes();
|
||||
|
||||
candidates.removeIf(refAndType -> {
|
||||
PsiClassType type = refAndType.type;
|
||||
return ArrayUtil.contains(type, overridingMethodThrownException);
|
||||
});
|
||||
|
||||
if (candidates.isEmpty()) return null;
|
||||
}
|
||||
}
|
||||
|
||||
return candidates.stream().map(exceptionType -> {
|
||||
PsiJavaCodeReferenceElement reference = exceptionType.ref;
|
||||
String description = JavaErrorMessages.message("exception.is.never.thrown", JavaHighlightUtil.formatType(exceptionType.type));
|
||||
LocalQuickFix quickFix = new MethodThrowsFix(method, exceptionType.type, false, false);
|
||||
return inspectionManager.createProblemDescriptor(reference, description, quickFix, ProblemHighlightType.LIKE_UNUSED_SYMBOL, true);
|
||||
}).toArray(ProblemDescriptor[]::new);
|
||||
}
|
||||
|
||||
private static ReferenceAndType[] getThrownCheckedExceptions(PsiMethod method) {
|
||||
return Stream
|
||||
.of(method.getThrowsList().getReferenceElements())
|
||||
.map(ref -> {
|
||||
PsiElement resolved = ref.resolve();
|
||||
if (resolved instanceof PsiClass) {
|
||||
return new ReferenceAndType(ref, (PsiClass)resolved);
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(ReferenceAndType[]::new);
|
||||
}
|
||||
|
||||
private static class ReferenceAndType {
|
||||
private final PsiJavaCodeReferenceElement ref;
|
||||
private final PsiClassType type;
|
||||
|
||||
private ReferenceAndType(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiClass aClass) {
|
||||
this.ref = ref;
|
||||
type = new PsiImmediateClassType(aClass, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.intellij.codeInspection.unneededThrows;
|
||||
|
||||
import com.intellij.codeInspection.ex.InspectionElementsMerger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RedundantThrowsInspectionMerger extends InspectionElementsMerger {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getMergedToolName() {
|
||||
return "RedundantThrows";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getSourceToolNames() {
|
||||
return new String[] {"RedundantThrowsDeclaration"};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getSuppressIds() {
|
||||
return getSourceToolNames();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@ class Test {
|
||||
abstract void call(String[] f) throws FileNotFoundException, IOException;
|
||||
}
|
||||
|
||||
void use(Target target) throws IOException {
|
||||
void use(Target target) throws <warning descr="Exception 'java.io.IOException' is never thrown in the method">IOException</warning> {
|
||||
try {
|
||||
target.call("");
|
||||
} catch (FileNotFoundException e) {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "true"
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Add 'java.io.IOException' to 'a.f' throws list" "true"
|
||||
// "Add 'IOException' to 'a.f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "true"
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
void f() throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
class b extends a {
|
||||
void f() {
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "true"
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "true"
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Add 'java.io.IOException' to 'a.f' throws list" "true"
|
||||
// "Add 'IOException' to 'a.f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "true"
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "false"
|
||||
// "Remove 'IOException' from 'f' throws list" "false"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "false"
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Remove 'IOException' from 'f' throws list" "false"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
void f() throws <caret>IOException {
|
||||
}
|
||||
}
|
||||
|
||||
class b extends a {
|
||||
void f() throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Remove 'java.io.IOException' from 'f' throws list" "true"
|
||||
// "Remove 'IOException' from 'f' throws list" "true"
|
||||
import java.io.*;
|
||||
|
||||
class a {
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Suppress for method" "true"
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
class Main {
|
||||
@SuppressWarnings("RedundantThrowsDeclaration")
|
||||
public void test() throws Exception, FileNotFoundException, IOException {}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Suppress for method" "false"
|
||||
// "Suppress for method" "true"
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ import com.intellij.codeInspection.reference.EntryPoint;
|
||||
import com.intellij.codeInspection.reference.RefElement;
|
||||
import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationLocalInspection;
|
||||
import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
|
||||
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase;
|
||||
import com.intellij.lang.Language;
|
||||
@@ -100,7 +100,7 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
new SillyAssignmentInspection(),
|
||||
new AccessStaticViaInstance(),
|
||||
new DeprecationInspection(),
|
||||
new RedundantThrowsDeclaration(),
|
||||
new RedundantThrowsDeclarationLocalInspection(),
|
||||
new UnusedImportLocalInspection(),
|
||||
new UncheckedWarningLocalInspection()
|
||||
};
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ package com.intellij.java.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationLocalInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public class MethodThrowsTest extends LightQuickFixParameterizedTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[] {new RedundantThrowsDeclaration()};
|
||||
return new LocalInspectionTool[] {new RedundantThrowsDeclarationLocalInspection()};
|
||||
}
|
||||
|
||||
public void test() throws Exception { doAllTests(); }
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import com.intellij.codeInspection.duplicateThrows.DuplicateThrowsInspection;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection;
|
||||
import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationLocalInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class Suppress15InspectionsTest extends LightQuickFixParameterizedTestCas
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{
|
||||
new RedundantThrowsDeclaration(),
|
||||
new RedundantThrowsDeclarationLocalInspection(),
|
||||
new SillyAssignmentInspection(),
|
||||
new AccessStaticViaInstance(),
|
||||
new DeprecationInspection(),
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ import com.intellij.codeInspection.deprecation.DeprecationInspection;
|
||||
import com.intellij.codeInspection.javaDoc.JavaDocReferenceInspection;
|
||||
import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection;
|
||||
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationLocalInspection;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -44,7 +44,7 @@ public class SuppressNonInspectionsTest extends LightQuickFixParameterizedTestCa
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{
|
||||
new RedundantThrowsDeclaration(),
|
||||
new RedundantThrowsDeclarationLocalInspection(),
|
||||
new SillyAssignmentInspection(),
|
||||
new AccessStaticViaInstance(),
|
||||
new DeprecationInspection(),
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.intellij.java.codeInspection;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrows;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationInspection;
|
||||
import com.intellij.testFramework.InspectionTestCase;
|
||||
|
||||
public class RedundantThrowTest extends InspectionTestCase {
|
||||
@@ -30,7 +30,7 @@ public class RedundantThrowTest extends InspectionTestCase {
|
||||
}
|
||||
|
||||
private void doTest(boolean checkRange) throws Exception {
|
||||
final RedundantThrows tool = new RedundantThrows();
|
||||
final RedundantThrowsDeclarationInspection tool = new RedundantThrowsDeclarationInspection();
|
||||
doTest("redundantThrow/" + getTestName(false), tool, checkRange);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class RedundantThrowTest extends InspectionTestCase {
|
||||
public void testRemote() throws Exception { doTest(); }
|
||||
|
||||
public void testEntryPoint() throws Exception {
|
||||
final RedundantThrows tool = new RedundantThrows();
|
||||
final RedundantThrowsDeclarationInspection tool = new RedundantThrowsDeclarationInspection();
|
||||
doTest("redundantThrow/" + getTestName(true), tool, false, true);
|
||||
}
|
||||
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.GlobalSearchScopeUtil;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.stubs.StubIndex;
|
||||
import com.intellij.psi.util.PsiSuperMethodUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class JavaOverridingMethodUtil {
|
||||
private static final int MAX_OVERRIDDEN_METHOD_SEARCH = 20;
|
||||
|
||||
@Nullable
|
||||
public static Stream<PsiMethod> getOverridingMethodsIfCheapEnough(@NotNull PsiMethod method,
|
||||
@Nullable GlobalSearchScope searchScope,
|
||||
@NotNull Predicate<PsiMethod> preFilter) {
|
||||
Project project = method.getProject();
|
||||
String name = method.getName();
|
||||
SearchScope useScope = method.getUseScope();
|
||||
GlobalSearchScope effectiveSearchScope = GlobalSearchScopeUtil.toGlobalSearchScope(useScope, project);
|
||||
if (searchScope != null) {
|
||||
effectiveSearchScope = effectiveSearchScope.intersectWith(searchScope);
|
||||
}
|
||||
PsiMethod[] methods =
|
||||
StubIndex.getElements(JavaStubIndexKeys.METHODS, name, project, effectiveSearchScope, PsiMethod.class)
|
||||
.stream()
|
||||
.filter(m -> m != method)
|
||||
.filter(preFilter)
|
||||
.limit(MAX_OVERRIDDEN_METHOD_SEARCH + 1)
|
||||
.toArray(PsiMethod[]::new);
|
||||
|
||||
// search should be deterministic
|
||||
if (methods.length > MAX_OVERRIDDEN_METHOD_SEARCH) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Stream.of(methods).filter(candidate -> PsiSuperMethodUtil.isSuperMethod(candidate, method));
|
||||
}
|
||||
}
|
||||
+3
-34
@@ -27,28 +27,21 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.GlobalSearchScopeUtil;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.stubs.StubIndex;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiSuperMethodUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ThreeState;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.JavaOverridingMethodUtil;
|
||||
import com.siyeh.ig.psiutils.MethodUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MissingOverrideAnnotationInspection extends BaseJavaBatchLocalInspectionTool implements CleanupLocalInspectionTool{
|
||||
private static final int MAX_OVERRIDDEN_METHOD_SEARCH = 20;
|
||||
private static final String OVERRIDE_SHORT_NAME = StringUtil.getShortName(CommonClassNames.JAVA_LANG_OVERRIDE);
|
||||
|
||||
@SuppressWarnings({"PublicField"})
|
||||
@@ -138,7 +131,8 @@ public class MissingOverrideAnnotationInspection extends BaseJavaBatchLocalInspe
|
||||
Project project = method.getProject();
|
||||
LanguageLevel minimal = Objects.requireNonNull(method.getContainingClass()).isInterface() ? LanguageLevel.JDK_1_6 : LanguageLevel.JDK_1_5;
|
||||
|
||||
Stream<PsiMethod> overridingMethods = getOverridingMethodsIfCheapEnough(method, getLanguageLevelScope(minimal, project), m -> {
|
||||
Stream<PsiMethod> overridingMethods = JavaOverridingMethodUtil
|
||||
.getOverridingMethodsIfCheapEnough(method, getLanguageLevelScope(minimal, project), m -> {
|
||||
for (PsiAnnotation annotation : m.getModifierList().getAnnotations()) {
|
||||
PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
|
||||
if (ref != null && OVERRIDE_SHORT_NAME.equals(ref.getReferenceName())) {
|
||||
@@ -231,29 +225,4 @@ public class MissingOverrideAnnotationInspection extends BaseJavaBatchLocalInspe
|
||||
.map(Module::getModuleScope)
|
||||
.toArray(GlobalSearchScope[]::new));
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static Stream<PsiMethod> getOverridingMethodsIfCheapEnough(@NotNull PsiMethod method,
|
||||
@NotNull GlobalSearchScope searchScope,
|
||||
@NotNull Predicate<PsiMethod> preFilter) {
|
||||
Project project = method.getProject();
|
||||
String name = method.getName();
|
||||
SearchScope useScope = method.getUseScope();
|
||||
GlobalSearchScope effectiveSearchScope = GlobalSearchScopeUtil.toGlobalSearchScope(useScope, project).intersectWith(searchScope);
|
||||
PsiMethod[] methods =
|
||||
StubIndex.getElements(JavaStubIndexKeys.METHODS, name, project, effectiveSearchScope, PsiMethod.class)
|
||||
.stream()
|
||||
.filter(m -> m != method)
|
||||
.filter(preFilter)
|
||||
.limit(MAX_OVERRIDDEN_METHOD_SEARCH + 1)
|
||||
.toArray(PsiMethod[]::new);
|
||||
|
||||
// search should be deterministic
|
||||
if (methods.length > MAX_OVERRIDDEN_METHOD_SEARCH) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Stream.of(methods).filter(candidate -> PsiSuperMethodUtil.isSuperMethod(candidate, method));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports exceptions that are declared in a method's signature but never thrown by the method itself.
|
||||
Only final, private or static methods are analyzed. For other methods, global code analysis is required.
|
||||
For batch inspections, this can be achieved using
|
||||
<nobr><i>Declaration Redundancy | Redundant throws clause</i>.</nobr>
|
||||
</body>
|
||||
</html>
|
||||
@@ -616,6 +616,7 @@
|
||||
<externalProjectDataService implementation="com.intellij.externalSystem.JavaProjectDataService"/>
|
||||
<inspectionElementsMerger implementation="com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionMerger"/>
|
||||
<inspectionElementsMerger implementation="com.intellij.codeInspection.java18api.Java8MapApiInspectionMerger"/>
|
||||
<inspectionElementsMerger implementation="com.intellij.codeInspection.unneededThrows.RedundantThrowsInspectionMerger"/>
|
||||
|
||||
<globalInspection groupPath="Java" language="JAVA" shortName="unused" displayName="Unused declaration" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.declaration.redundancy" enabledByDefault="true" level="WARNING"
|
||||
@@ -645,9 +646,9 @@
|
||||
implementationClass="com.intellij.codeInspection.sameReturnValue.SameReturnValueInspection"/>
|
||||
<globalInspection groupPath="Java" language="JAVA" shortName="EmptyMethod" displayName="Empty method" groupKey="group.names.declaration.redundancy" enabledByDefault="true" groupBundle="messages.InspectionsBundle"
|
||||
level="WARNING" implementationClass="com.intellij.codeInspection.emptyMethod.EmptyMethodInspection"/>
|
||||
<globalInspection groupPath="Java" language="JAVA" shortName="RedundantThrows" displayName="Redundant throws clause" groupKey="group.names.declaration.redundancy" groupBundle="messages.InspectionsBundle"
|
||||
<globalInspection groupPath="Java" language="JAVA" shortName="RedundantThrows" cleanupTool="true" displayName="Redundant throws clause" groupKey="group.names.declaration.redundancy" groupBundle="messages.InspectionsBundle"
|
||||
enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.unneededThrows.RedundantThrows"/>
|
||||
implementationClass="com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationInspection"/>
|
||||
<globalInspection groupPath="Java" language="JAVA" shortName="Java9RedundantRequiresStatement"
|
||||
groupBundle="messages.InspectionsBundle" groupKey="group.names.declaration.redundancy"
|
||||
enabledByDefault="true" level="WARNING" displayName="Redundant 'requires' statement in module-info"
|
||||
@@ -740,9 +741,6 @@
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="DefaultAnnotationParam" bundle="messages.InspectionsBundle" key="inspection.default.annotation.param" groupKey="group.names.declaration.redundancy"
|
||||
enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.DefaultAnnotationParamInspection" />
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="RedundantThrowsDeclaration" bundle="messages.InspectionsBundle" key="redundant.throws.declaration"
|
||||
groupKey="group.names.declaration.redundancy" enabledByDefault="false" level="WARNING" cleanupTool="true"
|
||||
implementationClass="com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclaration" />
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="AccessStaticViaInstance" bundle="messages.InspectionsBundle" key="access.static.via.instance" groupKey="group.names.declaration.redundancy"
|
||||
enabledByDefault="true" level="WARNING" cleanupTool="true" alternativeId="static-access"
|
||||
implementationClass="com.intellij.codeInspection.accessStaticViaInstance.AccessStaticViaInstance" />
|
||||
|
||||
Reference in New Issue
Block a user