IDEA-60595 (Logger initialized with foreign class multiple logger classes)

This commit is contained in:
Bas Leijdekkers
2012-07-09 21:01:58 +02:00
parent 8c3ab9c48a
commit 31bab59d9e
4 changed files with 81 additions and 149 deletions
@@ -1689,7 +1689,8 @@ assertequals.may.be.assertsame.problem.descriptor=<code>#ref()</code> may be 'as
logger.initialized.with.foreign.class.quickfix=Replace with ''{0}.class''
logger.initialized.with.foreign.class.problem.descriptor=Logger initializer with foreign class <code>#ref</code> #loc
logger.initialized.with.foreign.class.display.name=Logger initialized with foreign class
logger.factory.method.name=Logger factory &method:
logger.factory.methods.name=Logger factory methods
logger.factory.class.names=Logger factory class names
make.static.final.quickfix=Make ''{0}'' static final
logging.condition.disagrees.with.log.statement.display.name=Logging condition does not match log statement
logging.condition.disagrees.with.log.statement.problem.descriptor=Logging condition <code>#ref()</code> does not match ''{0}()'' log statement #loc
@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.siyeh.ig.logging.LoggerInitializedWithForeignClassInspection.Form">
<grid id="27dc6" binding="contentPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="0" vgap="4">
<margin top="4" left="4" bottom="4" right="4"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="ba10c" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="ec38c"/>
<text resource-bundle="com/siyeh/InspectionGadgetsBundle" key="logger.name.option"/>
</properties>
</component>
<vspacer id="cd8a0">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="ec38c" class="javax.swing.JTextField" binding="loggerClassNameTextField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="1e40b" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<labelFor value="b0b6"/>
<text resource-bundle="com/siyeh/InspectionGadgetsBundle" key="logger.factory.method.name"/>
</properties>
</component>
<component id="b0b6" class="javax.swing.JTextField" binding="loggerFactoryMethodNameTextField" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
</children>
</grid>
</form>
@@ -1,5 +1,5 @@
/*
* Copyright 2008 Bas Leijdekkers
* Copyright 2008-2012 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,57 +15,72 @@
*/
package com.siyeh.ig.logging;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ui.ListTable;
import com.intellij.codeInspection.ui.ListWrappingTableModel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.openapi.project.Project;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.ui.UiUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.text.Document;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LoggerInitializedWithForeignClassInspection
extends BaseInspection {
public class LoggerInitializedWithForeignClassInspection extends BaseInspection {
@NonNls private static final String DEFAULT_LOGGER_CLASS_NAMES = "org.apache.log4j.Logger,org.slf4j.LoggerFactory";
@NonNls private static final String DEFAULT_FACTORY_METHOD_NAMES = "getLogger,getLogger";
@SuppressWarnings({"PublicField"})
public String loggerClassName = "org.apache.log4j.Logger";
public String loggerClassName = DEFAULT_LOGGER_CLASS_NAMES;
private final List<String> loggerFactoryClassNames = new ArrayList();
@SuppressWarnings({"PublicField"})
public String loggerFactoryMethodName = "getLogger";
public String loggerFactoryMethodName = DEFAULT_FACTORY_METHOD_NAMES;
private final List<String> loggerFactoryMethodNames = new ArrayList();
@Override
@NotNull
public String getDisplayName() {
return InspectionGadgetsBundle.message(
"logger.initialized.with.foreign.class.display.name");
return InspectionGadgetsBundle.message("logger.initialized.with.foreign.class.display.name");
}
@Override
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"logger.initialized.with.foreign.class.problem.descriptor");
return InspectionGadgetsBundle.message("logger.initialized.with.foreign.class.problem.descriptor");
}
@Override
public JComponent createOptionsPanel() {
return new Form().getContentPanel();
final ListTable table = new ListTable(
new ListWrappingTableModel(Arrays.asList(loggerFactoryClassNames, loggerFactoryMethodNames),
InspectionGadgetsBundle.message("logger.factory.class.names"),
InspectionGadgetsBundle.message("logger.factory.methods.name")));
return UiUtils.createAddRemovePanel(table);
}
@Override
@Nullable
protected InspectionGadgetsFix buildFix(Object... infos) {
return new LoggerInitializedWithForeignClassFix((String)infos[0]);
}
private static class LoggerInitializedWithForeignClassFix
extends InspectionGadgetsFix {
private static class LoggerInitializedWithForeignClassFix extends InspectionGadgetsFix {
private final String newClassName;
@@ -73,6 +88,7 @@ public class LoggerInitializedWithForeignClassInspection
this.newClassName = newClassName;
}
@Override
@NotNull
public String getName() {
return InspectionGadgetsBundle.message(
@@ -80,28 +96,26 @@ public class LoggerInitializedWithForeignClassInspection
newClassName);
}
protected void doFix(Project project, ProblemDescriptor descriptor)
throws IncorrectOperationException {
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
if (!(element instanceof PsiClassObjectAccessExpression)) {
return;
}
final PsiClassObjectAccessExpression classObjectAccessExpression =
(PsiClassObjectAccessExpression)element;
replaceExpression(classObjectAccessExpression,
newClassName + ".class");
final PsiClassObjectAccessExpression classObjectAccessExpression = (PsiClassObjectAccessExpression)element;
replaceExpression(classObjectAccessExpression, newClassName + ".class");
}
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new LoggerInitializedWithForeignClassVisitor();
}
private class LoggerInitializedWithForeignClassVisitor
extends BaseInspectionVisitor {
private class LoggerInitializedWithForeignClassVisitor extends BaseInspectionVisitor {
public void visitClassObjectAccessExpression(
PsiClassObjectAccessExpression expression) {
@Override
public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
super.visitClassObjectAccessExpression(expression);
final PsiElement parent = expression.getParent();
if (!(parent instanceof PsiExpressionList)) {
@@ -111,10 +125,13 @@ public class LoggerInitializedWithForeignClassInspection
if (!(grandParent instanceof PsiMethodCallExpression)) {
return;
}
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression)grandParent;
final PsiClass containingClass = PsiTreeUtil.getParentOfType(
expression, PsiClass.class);
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent;
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
final PsiExpression[] expressions = argumentList.getExpressions();
if (expressions.length != 1) {
return;
}
final PsiClass containingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
if (containingClass == null) {
return;
}
@@ -122,19 +139,23 @@ public class LoggerInitializedWithForeignClassInspection
if (containingClassName == null) {
return;
}
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final String referenceName = methodExpression.getReferenceName();
if (!loggerFactoryMethodName.equals(referenceName)) {
return;
}
final PsiMethod method = methodCallExpression.resolveMethod();
if (method == null) {
return;
}
final PsiClass aClass = method.getContainingClass();
if (aClass == null) {
return;
}
final String className = aClass.getQualifiedName();
if (!loggerClassName.equals(className)) {
final int index = loggerFactoryClassNames.indexOf(className);
if (index < 0) {
return;
}
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
final String referenceName = methodExpression.getReferenceName();
final String loggerFactoryMethodName = loggerFactoryMethodNames.get(index);
if (!loggerFactoryMethodName.equals(referenceName)) {
return;
}
final PsiTypeElement operand = expression.getOperand();
@@ -154,60 +175,20 @@ public class LoggerInitializedWithForeignClassInspection
}
}
class Form {
private JPanel contentPanel;
private JTextField loggerClassNameTextField;
private JTextField loggerFactoryMethodNameTextField;
Form() {
loggerClassNameTextField.setText(loggerClassName);
final DocumentListener listener = new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
textChanged();
}
public void insertUpdate(DocumentEvent e) {
textChanged();
}
public void removeUpdate(DocumentEvent e) {
textChanged();
}
private void textChanged() {
loggerClassName = loggerClassNameTextField.getText();
}
};
final Document document = loggerClassNameTextField.getDocument();
document.addDocumentListener(listener);
loggerFactoryMethodNameTextField.setText(loggerFactoryMethodName);
final DocumentListener factoryListener = new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
textChanged();
}
public void insertUpdate(DocumentEvent e) {
textChanged();
}
public void removeUpdate(DocumentEvent e) {
textChanged();
}
private void textChanged() {
loggerClassName = loggerClassNameTextField.getText();
}
};
final Document factoryDocument =
loggerFactoryMethodNameTextField.getDocument();
factoryDocument.addDocumentListener(factoryListener);
}
public JComponent getContentPanel() {
return contentPanel;
@Override
public void readSettings(Element element) throws InvalidDataException {
super.readSettings(element);
parseString(loggerClassName, loggerFactoryClassNames);
parseString(loggerFactoryMethodName, loggerFactoryMethodNames);
if (loggerFactoryClassNames.size() != loggerFactoryMethodNames.size()) {
parseString(DEFAULT_LOGGER_CLASS_NAMES, loggerFactoryClassNames);
parseString(DEFAULT_FACTORY_METHOD_NAMES, loggerFactoryMethodNames);
}
}
}
@Override
public void writeSettings(Element element) throws WriteExternalException {
loggerClassName = formatString(loggerFactoryClassNames);
loggerFactoryMethodName = formatString(loggerFactoryMethodNames);
super.writeSettings(element);
}}
@@ -1,8 +1,10 @@
<html>
<body>
This inspection reports any <b>Logger</b>s which are
initialized with a class literal from a different class than the <b>Logger</b>
This inspection reports any <b>Logger</b>s which are initialized with a class literal from a different class than the <b>Logger</b>
is contained in.
<!-- tooltip end -->
<p>
Use the table below to specify the logger factory classes and logger factory methods recognized by this inspection.
<p>
<small>New in 8, Powered by InspectionGadgets</small>
</body>