diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index c009aee3ccb7..f81c58ddd173 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1740,6 +1740,9 @@ log.method.name=Logging method name log.condition.text=Log condition text ignore.if.annotated.by=Ignore if annotated by ignore.parameter.if.annotated.by=Ignore parameter if it is annotated by +ignore.classes.annotated.by=Ignore classes annotated by +ignored.class.hierarchies.border.title=Ignore subclasses of +choose.class.hierarchy.to.ignore.title=Choose Class Hierarchy to Ignore unqualified.inner.class.access.display.name=Unqualified inner class access unqualified.inner.class.access.problem.descriptor=#ref is not qualified with outer class #loc unqualified.inner.class.access.quickfix=Qualify with outer class diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/ClassWithoutLoggerInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/ClassWithoutLoggerInspection.java index e062e3379a5f..3a1e9dfdab76 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/logging/ClassWithoutLoggerInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/logging/ClassWithoutLoggerInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2019 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. @@ -15,16 +15,20 @@ */ package com.siyeh.ig.logging; -import com.intellij.codeInspection.ui.ListTable; -import com.intellij.codeInspection.ui.ListWrappingTableModel; +import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInspection.util.SpecialAnnotationsUtil; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.ui.ScrollPaneFactory; +import com.intellij.ui.components.JBTabbedPane; import com.intellij.util.ui.CheckBox; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.ui.ExternalizableStringSet; import com.siyeh.ig.ui.UiUtils; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -34,6 +38,7 @@ import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.List; +import java.util.stream.Stream; public class ClassWithoutLoggerInspection extends BaseInspection { @@ -51,19 +56,33 @@ public class ClassWithoutLoggerInspection extends BaseInspection { */ public boolean ignoreSuperLoggers = false; + @SuppressWarnings("PublicField") public final ExternalizableStringSet annotations = new ExternalizableStringSet(); + @SuppressWarnings("PublicField") public final ExternalizableStringSet ignoredClasses = new ExternalizableStringSet("java.lang.Throwable"); + public ClassWithoutLoggerInspection() { - parseString(this.loggerNamesString, this.loggerNames); + parseString(loggerNamesString, loggerNames); } @Override public JComponent createOptionsPanel() { - final JComponent panel = new JPanel(new BorderLayout()); - final ListTable table = new ListTable(new ListWrappingTableModel(loggerNames, InspectionGadgetsBundle.message("logger.class.name"))); - final JPanel tablePanel = UiUtils.createAddRemoveTreeClassChooserPanel(table, InspectionGadgetsBundle.message("choose.logger.class")); + final JPanel loggerPanel = UiUtils.createTreeClassChooserList(loggerNames, InspectionGadgetsBundle.message("logger.class.name"), + InspectionGadgetsBundle.message("choose.logger.class")); + final JPanel annotationsListControl = + SpecialAnnotationsUtil.createSpecialAnnotationsListControl(annotations, + InspectionGadgetsBundle.message("ignore.classes.annotated.by")); + final JPanel ignoredClassesPanel = + UiUtils.createTreeClassChooserList(ignoredClasses, InspectionGadgetsBundle.message("ignored.class.hierarchies.border.title"), + InspectionGadgetsBundle.message("choose.class.hierarchy.to.ignore.title")); final CheckBox checkBox = new CheckBox(InspectionGadgetsBundle.message("super.class.logger.option"), this, "ignoreSuperLoggers"); - panel.add(tablePanel, BorderLayout.CENTER); + + final JComponent panel = new JPanel(new BorderLayout()); + panel.add(ignoredClassesPanel, BorderLayout.CENTER); panel.add(checkBox, BorderLayout.SOUTH); - return panel; + final JBTabbedPane tabs = new JBTabbedPane(SwingConstants.TOP); + tabs.add("Loggers", ScrollPaneFactory.createScrollPane(loggerPanel, true)); + tabs.add("Ignored classes", ScrollPaneFactory.createScrollPane(panel, true)); + tabs.add("Annotations", ScrollPaneFactory.createScrollPane(annotationsListControl, true)); + return tabs; } @Override @@ -87,7 +106,9 @@ public class ClassWithoutLoggerInspection extends BaseInspection { @Override public void writeSettings(@NotNull Element element) throws WriteExternalException { loggerNamesString = formatString(loggerNames); - super.writeSettings(element); + defaultWriteSettings(element, "annotations", "ignoredClasses"); + annotations.writeSettings(element, "annotations"); + ignoredClasses.writeSettings(element, "ignoredClasses"); } @Override @@ -99,31 +120,21 @@ public class ClassWithoutLoggerInspection extends BaseInspection { @Override public void visitClass(@NotNull PsiClass aClass) { - //no recursion to avoid drilldown - if (aClass.isInterface() || aClass.isEnum() || - aClass.isAnnotationType()) { + if (aClass.isInterface() || aClass.isEnum() || aClass.isAnnotationType() || aClass.getContainingClass() != null) { return; } - if (aClass instanceof PsiTypeParameter || - aClass instanceof PsiAnonymousClass) { + if (aClass instanceof PsiTypeParameter || aClass instanceof PsiAnonymousClass) { return; } - if (aClass.getContainingClass() != null) { + if (ignoredClasses.stream().anyMatch(ignoredClass -> InheritanceUtil.isInheritor(aClass, ignoredClass))) { return; } - final PsiField[] fields; - if (ignoreSuperLoggers) { - fields = aClass.getAllFields(); + if (AnnotationUtil.isAnnotated(aClass, annotations, AnnotationUtil.CHECK_EXTERNAL | AnnotationUtil.CHECK_HIERARCHY)) { + return; } - else { - fields = aClass.getFields(); - } - for (PsiField field : fields) { - if (isLogger(field)) { - if (PsiUtil.isAccessible(field, aClass, aClass)) { - return; - } - } + final PsiField[] fields = ignoreSuperLoggers ? aClass.getAllFields() : aClass.getFields(); + if (Stream.of(fields).anyMatch(field -> isLogger(field) && PsiUtil.isAccessible(field, aClass, aClass))) { + return; } registerClassError(aClass); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/ClassWithoutLoggerInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/ClassWithoutLoggerInspection.java deleted file mode 100644 index b7e31ab46361..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/ClassWithoutLoggerInspection.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.siyeh.igtest.logging; - -public class ClassWithoutLoggerInspection { - private ClassWithoutLoggerInspection() { - } - - public static void main(String[] args) { - - } -} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/Annotation.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/Annotation.java new file mode 100644 index 000000000000..0acd287edf42 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/Annotation.java @@ -0,0 +1,4 @@ +import test.*; + +@Entity +class Annotation {} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/ClassWithLogger.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/ClassWithLogger.java new file mode 100644 index 000000000000..46bed057b95e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/ClassWithLogger.java @@ -0,0 +1,6 @@ +import java.util.logging.*; + +class ClassWithLogger { + + public static final Logger LOG = Logger.getLogger("test"); +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/ClassWithoutLogger.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/ClassWithoutLogger.java new file mode 100644 index 000000000000..d6474ecb7033 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/ClassWithoutLogger.java @@ -0,0 +1,10 @@ +package com.siyeh.igtest.logging; + +public class ClassWithoutLogger { + private ClassWithoutLogger() { + } + + public static void main(String[] args) { + + } +} diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/MyException.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/MyException.java new file mode 100644 index 000000000000..3d551c212503 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/logging/class_without_logger/MyException.java @@ -0,0 +1,3 @@ +class MyException extends RuntimeException { + // no logger +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/logging/ClassWithoutLoggerInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/logging/ClassWithoutLoggerInspectionTest.java new file mode 100644 index 000000000000..154ba12fed86 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/logging/ClassWithoutLoggerInspectionTest.java @@ -0,0 +1,40 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.siyeh.ig.logging; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; + +/** + * @author Bas Leijdekkers + */ +public class ClassWithoutLoggerInspectionTest extends LightInspectionTestCase { + + public void testClassWithoutLogger() { doTest();} + public void testClassWithLogger() { doTest();} + public void testMyException() { doTest();} + public void testAnnotation() { doTest();} + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + final ClassWithoutLoggerInspection inspection = new ClassWithoutLoggerInspection(); + inspection.annotations.add("test.Entity"); + return inspection; + } + + @Override + protected String[] getEnvironmentClasses() { + return new String[] { + "package java.util.logging;" + + "public class Logger {" + + " public static Logger getLogger(String name) {" + + " return null;" + + " }" + + "}", + + "package test;" + + "public @interface Entity {}" + }; + } +}