mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
merged CVS and Subversion versions
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
Query string should be constant
|
||||
Reuse of local variable.
|
||||
Logging not wrapped in if block
|
||||
Public method without logging
|
||||
Logger constructed without the current class name as argument.
|
||||
Class initialization circularity
|
||||
Incorrect lazy initialization of static field
|
||||
setter or getter with non-standard name
|
||||
Avoid repeated casting
|
||||
arithmetic operations on volatile types
|
||||
Field has setter but no getter
|
||||
Name with forbidden component
|
||||
Paired open/close for Sockets
|
||||
Paired open/close for Channels
|
||||
Paired acquire/release for Locks
|
||||
|
||||
Inheritance as type def (change the EmptyClass inspection)
|
||||
changing multiply/divide to shift may change precedence!
|
||||
Fix the "variable accessed in synchronized and unsynchronized contexts" to deal
|
||||
with unsynchronized private methods called only from synchronized contexts
|
||||
SerialVersionUID calculation
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.siyeh.ig.abstraction;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import com.siyeh.ig.StatementInspection;
|
||||
|
||||
public class InstanceofChainInspection extends StatementInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Chain of 'instanceof' checks";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.ABSTRACTION_GROUP_NAME;
|
||||
}
|
||||
|
||||
protected String buildErrorString(PsiElement location) {
|
||||
return "Chain of 'instanceof' checks indicates abstraction faiulre #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new InstanceofChainVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class InstanceofChainVisitor extends BaseInspectionVisitor {
|
||||
private InstanceofChainVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitIfStatement(PsiIfStatement statement) {
|
||||
super.visitIfStatement(statement);
|
||||
final PsiElement parent = statement.getParent();
|
||||
if (parent instanceof PsiIfStatement) {
|
||||
final PsiIfStatement parentStatement = (PsiIfStatement) parent;
|
||||
final PsiStatement elseBranch = parentStatement.getElseBranch();
|
||||
if (statement.equals(elseBranch)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int numChecks = 0;
|
||||
PsiIfStatement branch = statement;
|
||||
while (branch != null) {
|
||||
final PsiExpression condition = branch.getCondition();
|
||||
if (!isInstanceofCheck(condition)) {
|
||||
return;
|
||||
}
|
||||
numChecks++;
|
||||
|
||||
final PsiStatement elseBranch = branch.getElseBranch();
|
||||
if (elseBranch instanceof PsiIfStatement) {
|
||||
branch = (PsiIfStatement) elseBranch;
|
||||
} else {
|
||||
branch = null;
|
||||
}
|
||||
}
|
||||
if (numChecks < 2) {
|
||||
return;
|
||||
}
|
||||
registerStatementError(statement);
|
||||
}
|
||||
|
||||
private boolean isInstanceofCheck(PsiExpression condition) {
|
||||
if (condition == null) {
|
||||
return false;
|
||||
} else if (condition instanceof PsiInstanceOfExpression) {
|
||||
return true;
|
||||
} else if (condition instanceof PsiBinaryExpression) {
|
||||
final PsiBinaryExpression binaryExpression = (PsiBinaryExpression) condition;
|
||||
final PsiExpression lhs = binaryExpression.getLOperand();
|
||||
final PsiExpression rhs = binaryExpression.getROperand();
|
||||
return isInstanceofCheck(lhs) && isInstanceofCheck(rhs);
|
||||
} else if (condition instanceof PsiParenthesizedExpression) {
|
||||
final PsiExpression contents = ((PsiParenthesizedExpression) condition).getExpression();
|
||||
return isInstanceofCheck(contents);
|
||||
} else if (condition instanceof PsiPrefixExpression) {
|
||||
final PsiExpression contents = ((PsiPrefixExpression) condition).getOperand();
|
||||
return isInstanceofCheck(contents);
|
||||
} else if (condition instanceof PsiPostfixExpression) {
|
||||
final PsiExpression contents = ((PsiPostfixExpression) condition).getOperand();
|
||||
return isInstanceofCheck(contents);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.siyeh.ig.bugs;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.siyeh.ig.*;
|
||||
|
||||
public class StaticCallOnSubclassInspection extends ExpressionInspection {
|
||||
private final StaticCallOnSubclassFix fix = new StaticCallOnSubclassFix();
|
||||
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Static method referenced via subclass";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.BUGS_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) location.getParent().getParent();
|
||||
final PsiMethod method = methodCall.resolveMethod();
|
||||
final String declaringClass = method.getContainingClass().getName();
|
||||
final String referencedClass = methodCall.getMethodExpression().getQualifier().getText();
|
||||
return "Static method '#ref' declared on class " + declaringClass + " but referenced via class" + referencedClass + " #loc";
|
||||
}
|
||||
|
||||
protected InspectionGadgetsFix buildFix(PsiElement location) {
|
||||
return fix;
|
||||
}
|
||||
|
||||
private static class StaticCallOnSubclassFix extends InspectionGadgetsFix {
|
||||
public String getName() {
|
||||
return "Rationalize static method call";
|
||||
}
|
||||
|
||||
public void applyFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiIdentifier name = (PsiIdentifier) descriptor.getPsiElement();
|
||||
final PsiReferenceExpression expression = (PsiReferenceExpression) name.getParent();
|
||||
final PsiMethodCallExpression call = (PsiMethodCallExpression) expression.getParent();
|
||||
final PsiMethod method = call.resolveMethod();
|
||||
final String methodName = expression.getReferenceName();
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
final PsiExpressionList argumentList = call.getArgumentList();
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final String argText = args[0].getText();
|
||||
replaceExpression(project, call, containingClass.getName() + '.' + methodName + "(" + argText + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new StaticCallOnSubclassVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class StaticCallOnSubclassVisitor extends BaseInspectionVisitor {
|
||||
private StaticCallOnSubclassVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression call) {
|
||||
super.visitMethodCallExpression(call);
|
||||
final PsiReferenceExpression methodExpression = call.getMethodExpression();
|
||||
if (methodExpression == null) {
|
||||
return;
|
||||
}
|
||||
final PsiElement qualifier = methodExpression.getQualifier();
|
||||
if (!(qualifier instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement referent = ((PsiReference) qualifier).resolve();
|
||||
if (!(referent instanceof PsiClass)) {
|
||||
return;
|
||||
}
|
||||
final PsiClass referencedClass = (PsiClass) referent;
|
||||
final PsiMethod method = call.resolveMethod();
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiClass declaringClass = method.getContainingClass();
|
||||
if (declaringClass.equals(referencedClass)) {
|
||||
return;
|
||||
}
|
||||
registerMethodCallError(call);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.siyeh.ig.encapsulation;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ExpressionInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
|
||||
public class UseOfAnotherObjectsPrivateFieldInspection extends ExpressionInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Accessing a non-public field of another object";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.ENCAPSULATION_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Direct access of non-public field #ref on another object #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new UseOfAnotherObjectsPrivateFieldVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class UseOfAnotherObjectsPrivateFieldVisitor extends BaseInspectionVisitor {
|
||||
private UseOfAnotherObjectsPrivateFieldVisitor(BaseInspection inspection,
|
||||
InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiExpression qualifier = expression.getQualifierExpression();
|
||||
if(qualifier == null || qualifier instanceof PsiThisExpression)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiElement referent = expression.resolve();
|
||||
if(referent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!(referent instanceof PsiField))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiField field = (PsiField)referent;
|
||||
if(!field.hasModifierProperty(PsiModifier.PRIVATE) &&
|
||||
!field.hasModifierProperty(PsiModifier.PROTECTED))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiElement fieldNameElement = expression.getReferenceNameElement();
|
||||
registerError(fieldNameElement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.siyeh.ig.errorhandling.BadExceptionCaughtInspection.Form">
|
||||
<grid id="9993d" binding="contentPanel" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="92" y="33" width="211" height="192"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane id="14807">
|
||||
<constraints>
|
||||
<xy x="0" y="0" width="211" height="163"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="b0978" class="javax.swing.JTable" binding="table">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="f6174" class="javax.swing.JButton" binding="deleteButton">
|
||||
<constraints>
|
||||
<xy x="105" y="168" width="106" height="24"/>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Delete"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="52926" class="javax.swing.JButton" binding="addButton">
|
||||
<constraints>
|
||||
<xy x="0" y="168" width="95" height="24"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Add"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
package com.siyeh.ig.errorhandling;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ExpressionInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import org.jdom.Element;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class BadExceptionCaughtInspection extends ExpressionInspection {
|
||||
public String exceptionCheckString =
|
||||
"java.lang.NullPointerException," +
|
||||
"java.lang.IllegalMonitorStateException," +
|
||||
"java.lang.ArrayOutOfBoundsException";
|
||||
|
||||
private List exceptionsList = new ArrayList(32);
|
||||
|
||||
{
|
||||
parseExceptionsString();
|
||||
}
|
||||
|
||||
public void readSettings(Element element) throws InvalidDataException {
|
||||
super.readSettings(element);
|
||||
parseExceptionsString();
|
||||
}
|
||||
|
||||
private void parseExceptionsString() {
|
||||
exceptionsList.clear();
|
||||
final String[] strings = exceptionCheckString.split(",");
|
||||
for (int i = 0; i < strings.length; i++ ) {
|
||||
exceptionsList.add(strings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeSettings(Element element) throws WriteExternalException {
|
||||
formatCallCheckString();
|
||||
super.writeSettings(element);
|
||||
}
|
||||
|
||||
private void formatCallCheckString() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
boolean first = true;
|
||||
for (Iterator iterator = exceptionsList.iterator(); iterator.hasNext();) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
buffer.append(',');
|
||||
}
|
||||
final String exceptionName = (String) iterator.next();
|
||||
buffer.append(exceptionName);
|
||||
}
|
||||
exceptionCheckString = buffer.toString();
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Prohibitted exception caught";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.ERRORHANDLING_GROUP_NAME;
|
||||
}
|
||||
|
||||
public JComponent createOptionsPanel() {
|
||||
final Form form = new Form();
|
||||
return form.getContentPanel();
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Prohibitted exception '#ref' caught. #loc ";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new BadExceptionCaughtVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private class BadExceptionCaughtVisitor extends BaseInspectionVisitor {
|
||||
private BadExceptionCaughtVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitTryStatement(PsiTryStatement statement) {
|
||||
|
||||
super.visitTryStatement(statement);
|
||||
final PsiParameter[] catchBlockParameters = statement.getCatchBlockParameters();
|
||||
for (int i = 0; i < catchBlockParameters.length; i++) {
|
||||
final PsiParameter parameter = catchBlockParameters[i];
|
||||
if(parameter == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
final PsiType type = parameter.getType();
|
||||
if(type == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
final String text = type.getCanonicalText();
|
||||
if(text == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (Iterator iterator = exceptionsList.iterator(); iterator.hasNext();) {
|
||||
final String exceptionClass = (String) iterator.next();
|
||||
if (text.equals(exceptionClass)) {
|
||||
final PsiTypeElement typeElement = parameter.getTypeElement();
|
||||
registerError(typeElement);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class Form {
|
||||
private JPanel contentPanel;
|
||||
private JButton addButton;
|
||||
private JButton deleteButton;
|
||||
private JTable table;
|
||||
|
||||
public Form() {
|
||||
super();
|
||||
table.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
||||
table.setRowSelectionAllowed(true);
|
||||
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
table.setEnabled(true);
|
||||
final ReturnCheckSpecificationTableModel model =
|
||||
new ReturnCheckSpecificationTableModel();
|
||||
table.setModel(model);
|
||||
addButton.setEnabled(true);
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
exceptionsList.add("");
|
||||
model.fireTableStructureChanged();
|
||||
}
|
||||
});
|
||||
deleteButton.setEnabled(true);
|
||||
deleteButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final int[] selectedRows = table.getSelectedRows();
|
||||
Arrays.sort(selectedRows);
|
||||
for (int i = selectedRows.length - 1; i >= 0; i--) {
|
||||
exceptionsList.remove(selectedRows[i]);
|
||||
}
|
||||
model.fireTableStructureChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JComponent getContentPanel() {
|
||||
return contentPanel;
|
||||
}
|
||||
}
|
||||
|
||||
private class ReturnCheckSpecificationTableModel extends AbstractTableModel {
|
||||
|
||||
public int getRowCount() {
|
||||
return exceptionsList.size();
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String getColumnName(int columnIndex) {
|
||||
return "Exception class";
|
||||
}
|
||||
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return exceptionsList.get(rowIndex);
|
||||
}
|
||||
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
exceptionsList.set(rowIndex, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.siyeh.ig.errorhandling.BadExceptionDeclaredInspection.Form">
|
||||
<grid id="9993d" binding="contentPanel" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="92" y="33" width="211" height="192"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane id="14807">
|
||||
<constraints>
|
||||
<xy x="0" y="0" width="211" height="163"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="b0978" class="javax.swing.JTable" binding="table">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="f6174" class="javax.swing.JButton" binding="deleteButton">
|
||||
<constraints>
|
||||
<xy x="105" y="168" width="106" height="24"/>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Delete"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="52926" class="javax.swing.JButton" binding="addButton">
|
||||
<constraints>
|
||||
<xy x="0" y="168" width="95" height="24"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Add"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
package com.siyeh.ig.errorhandling;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.*;
|
||||
import org.jdom.Element;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class BadExceptionDeclaredInspection extends MethodInspection {
|
||||
public String exceptionCheckString = "java.lang.Throwable," +
|
||||
"java.lang.Exception," +
|
||||
"java.lang.Error," +
|
||||
"java.lang.RuntimeException," +
|
||||
"java.lang.NullPointerException," +
|
||||
"java.lang.ClassCastException," +
|
||||
"java.lang.ArrayOutOfBoundsException";
|
||||
|
||||
private List exceptionsList = new ArrayList(32);
|
||||
|
||||
{
|
||||
parseCallCheckString();
|
||||
}
|
||||
|
||||
public void readSettings(Element element) throws InvalidDataException {
|
||||
super.readSettings(element);
|
||||
parseCallCheckString();
|
||||
}
|
||||
|
||||
private void parseCallCheckString() {
|
||||
exceptionsList.clear();
|
||||
final String[] strings = exceptionCheckString.split(",");
|
||||
for (int i = 0; i < strings.length; i++ ) {
|
||||
exceptionsList.add(strings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeSettings(Element element) throws WriteExternalException {
|
||||
formatCallCheckString();
|
||||
super.writeSettings(element);
|
||||
}
|
||||
|
||||
private void formatCallCheckString() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
boolean first = true;
|
||||
for (Iterator iterator = exceptionsList.iterator(); iterator.hasNext();) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
buffer.append(',');
|
||||
}
|
||||
final String exceptionName = (String) iterator.next();
|
||||
buffer.append(exceptionName);
|
||||
}
|
||||
exceptionCheckString = buffer.toString();
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Prohibitted exception declared";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.ERRORHANDLING_GROUP_NAME;
|
||||
}
|
||||
|
||||
public JComponent createOptionsPanel() {
|
||||
final Form form = new Form();
|
||||
return form.getContentPanel();
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
final PsiThrowStatement throwStatement = (PsiThrowStatement) location.getParent();
|
||||
final PsiExpression exception = throwStatement.getException();
|
||||
final PsiType type = exception.getType();
|
||||
final String exceptionName = type.getPresentableText();
|
||||
return "Prohibitted exception '" + exceptionName + "' declared. #loc ";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new BadExceptionDeclaredVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private class BadExceptionDeclaredVisitor extends BaseInspectionVisitor {
|
||||
private BadExceptionDeclaredVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitMethod(PsiMethod method) {
|
||||
super.visitMethod(method);
|
||||
final PsiReferenceList throwsList = method.getThrowsList();
|
||||
if(throwsList ==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiJavaCodeReferenceElement[] references =
|
||||
throwsList.getReferenceElements();
|
||||
if(references == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < references.length; i++) {
|
||||
final PsiClass thrownClass = (PsiClass) references[i].resolve();
|
||||
if(thrownClass != null)
|
||||
{
|
||||
final String text = thrownClass.getQualifiedName();
|
||||
for (Iterator iterator = exceptionsList.iterator(); iterator.hasNext();) {
|
||||
final String exceptionClass = (String) iterator.next();
|
||||
if (text.equals(exceptionClass)) {
|
||||
registerError(references[i]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Form {
|
||||
private JPanel contentPanel;
|
||||
private JButton addButton;
|
||||
private JButton deleteButton;
|
||||
private JTable table;
|
||||
|
||||
public Form() {
|
||||
super();
|
||||
table.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
||||
table.setRowSelectionAllowed(true);
|
||||
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
table.setEnabled(true);
|
||||
final ReturnCheckSpecificationTableModel model =
|
||||
new ReturnCheckSpecificationTableModel();
|
||||
table.setModel(model);
|
||||
addButton.setEnabled(true);
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
exceptionsList.add("");
|
||||
model.fireTableStructureChanged();
|
||||
}
|
||||
});
|
||||
deleteButton.setEnabled(true);
|
||||
deleteButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final int[] selectedRows = table.getSelectedRows();
|
||||
Arrays.sort(selectedRows);
|
||||
for (int i = selectedRows.length - 1; i >= 0; i--) {
|
||||
exceptionsList.remove(selectedRows[i]);
|
||||
}
|
||||
model.fireTableStructureChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JComponent getContentPanel() {
|
||||
return contentPanel;
|
||||
}
|
||||
}
|
||||
|
||||
private class ReturnCheckSpecificationTableModel extends AbstractTableModel {
|
||||
|
||||
public int getRowCount() {
|
||||
return exceptionsList.size();
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String getColumnName(int columnIndex) {
|
||||
return "Exception class";
|
||||
}
|
||||
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return exceptionsList.get(rowIndex);
|
||||
}
|
||||
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
exceptionsList.set(rowIndex, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.siyeh.ig.errorhandling.BadExceptionThrownInspection.Form">
|
||||
<grid id="9993d" binding="contentPanel" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="92" y="33" width="211" height="192"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane id="14807">
|
||||
<constraints>
|
||||
<xy x="0" y="0" width="211" height="163"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="b0978" class="javax.swing.JTable" binding="table">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="f6174" class="javax.swing.JButton" binding="deleteButton">
|
||||
<constraints>
|
||||
<xy x="105" y="168" width="106" height="24"/>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Delete"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="52926" class="javax.swing.JButton" binding="addButton">
|
||||
<constraints>
|
||||
<xy x="0" y="168" width="95" height="24"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Add"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
package com.siyeh.ig.errorhandling;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ExpressionInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import org.jdom.Element;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EtchedBorder;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class BadExceptionThrownInspection extends ExpressionInspection {
|
||||
public String exceptionCheckString = "java.lang.Throwable," +
|
||||
"java.lang.Exception," +
|
||||
"java.lang.Error," +
|
||||
"java.lang.RuntimeException," +
|
||||
"java.lang.NullPointerException," +
|
||||
"java.lang.ClassCastException," +
|
||||
"java.lang.ArrayOutOfBoundsException";
|
||||
|
||||
private List exceptionsList = new ArrayList(32);
|
||||
|
||||
{
|
||||
parseCallCheckString();
|
||||
}
|
||||
|
||||
public void readSettings(Element element) throws InvalidDataException {
|
||||
super.readSettings(element);
|
||||
parseCallCheckString();
|
||||
}
|
||||
|
||||
private void parseCallCheckString() {
|
||||
exceptionsList.clear();
|
||||
final String[] strings = exceptionCheckString.split(",");
|
||||
for (int i = 0; i < strings.length; i++ ) {
|
||||
exceptionsList.add(strings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeSettings(Element element) throws WriteExternalException {
|
||||
formatCallCheckString();
|
||||
super.writeSettings(element);
|
||||
}
|
||||
|
||||
private void formatCallCheckString() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
boolean first = true;
|
||||
for (Iterator iterator = exceptionsList.iterator(); iterator.hasNext();) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
buffer.append(',');
|
||||
}
|
||||
final String exceptionName = (String) iterator.next();
|
||||
buffer.append(exceptionName);
|
||||
}
|
||||
exceptionCheckString = buffer.toString();
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Prohibitted exception thrown";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.ERRORHANDLING_GROUP_NAME;
|
||||
}
|
||||
|
||||
public JComponent createOptionsPanel() {
|
||||
final Form form = new Form();
|
||||
return form.getContentPanel();
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
final PsiThrowStatement throwStatement = (PsiThrowStatement) location.getParent();
|
||||
final PsiExpression exception = throwStatement.getException();
|
||||
final PsiType type = exception.getType();
|
||||
final String exceptionName = type.getPresentableText();
|
||||
return "Prohibitted exception '" + exceptionName + "' thrown. #loc ";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new BadExceptionThrownVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private class BadExceptionThrownVisitor extends BaseInspectionVisitor {
|
||||
private BadExceptionThrownVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitThrowStatement(PsiThrowStatement statement) {
|
||||
super.visitThrowStatement(statement);
|
||||
final PsiExpression exception = statement.getException();
|
||||
if(exception == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiType type = exception.getType();
|
||||
if(type == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final String text = type.getCanonicalText();
|
||||
for (Iterator iterator = exceptionsList.iterator(); iterator.hasNext();) {
|
||||
final String exceptionClass = (String) iterator.next();
|
||||
if(text.equals(exceptionClass))
|
||||
{
|
||||
registerStatementError(statement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Form {
|
||||
private JPanel contentPanel;
|
||||
private JButton addButton;
|
||||
private JButton deleteButton;
|
||||
private JTable table;
|
||||
|
||||
public Form() {
|
||||
super();
|
||||
table.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
|
||||
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
|
||||
table.setRowSelectionAllowed(true);
|
||||
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
table.setEnabled(true);
|
||||
final ReturnCheckSpecificationTableModel model =
|
||||
new ReturnCheckSpecificationTableModel();
|
||||
table.setModel(model);
|
||||
addButton.setEnabled(true);
|
||||
addButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
exceptionsList.add("");
|
||||
model.fireTableStructureChanged();
|
||||
}
|
||||
});
|
||||
deleteButton.setEnabled(true);
|
||||
deleteButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final int[] selectedRows = table.getSelectedRows();
|
||||
Arrays.sort(selectedRows);
|
||||
for (int i = selectedRows.length - 1; i >= 0; i--) {
|
||||
exceptionsList.remove(selectedRows[i]);
|
||||
}
|
||||
model.fireTableStructureChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JComponent getContentPanel() {
|
||||
return contentPanel;
|
||||
}
|
||||
}
|
||||
|
||||
private class ReturnCheckSpecificationTableModel extends AbstractTableModel {
|
||||
|
||||
public int getRowCount() {
|
||||
return exceptionsList.size();
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String getColumnName(int columnIndex) {
|
||||
return "Exception class";
|
||||
}
|
||||
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return exceptionsList.get(rowIndex);
|
||||
}
|
||||
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
exceptionsList.set(rowIndex, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.siyeh.ig.fixes;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiLocalVariable;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.RefactoringActionHandlerFactory;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
|
||||
public class InlineVariableFix extends InspectionGadgetsFix {
|
||||
|
||||
public String getName() {
|
||||
return "Inline variable";
|
||||
}
|
||||
|
||||
public void applyFix(Project project, ProblemDescriptor problemDescriptor) {
|
||||
final PsiElement nameElement = problemDescriptor.getPsiElement();
|
||||
final PsiLocalVariable variable = (PsiLocalVariable) nameElement.getParent();
|
||||
final RefactoringActionHandlerFactory factory =
|
||||
RefactoringActionHandlerFactory.getInstance();
|
||||
final RefactoringActionHandler inlineHandler = factory.createInlineHandler();
|
||||
inlineHandler.invoke(project, new PsiElement[]{variable}, null);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.siyeh.ig.internationalization;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ExpressionInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
|
||||
public class SimpleDateFormatWithoutLocaleInspection extends ExpressionInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Instantiating a SimpleDateFormat without a Locale";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.INTERNATIONALIZATION_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Instantiating a #ref without specifying a Locale in an internationalized context #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new SimpleDateFormatWithoutLocaleVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class SimpleDateFormatWithoutLocaleVisitor extends BaseInspectionVisitor {
|
||||
private SimpleDateFormatWithoutLocaleVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
super.visitNewExpression(expression);
|
||||
if(!TypeUtils.expressionHasType("java.util.SimpleDateFormat", expression))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiExpressionList argumentList = expression.getArgumentList();
|
||||
if(argumentList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
if(args == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if(TypeUtils.expressionHasType("java.util.Locale", args[i]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassReference();
|
||||
registerError(classReference);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
package com.siyeh.ig.junit;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.siyeh.ig.*;
|
||||
import com.siyeh.ig.psiutils.ClassUtils;
|
||||
|
||||
public class MisorderedAssertEqualsParametersInspection extends ExpressionInspection {
|
||||
private FlipParametersFix fix = new FlipParametersFix();
|
||||
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Misordered assertEquals parameters";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.JUNIT_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Parameters to #ref() in wrong order #loc";
|
||||
}
|
||||
|
||||
public InspectionGadgetsFix buildFix(PsiElement location) {
|
||||
return fix;
|
||||
}
|
||||
|
||||
private static class FlipParametersFix extends InspectionGadgetsFix {
|
||||
public String getName() {
|
||||
return "Flip compared parameters";
|
||||
}
|
||||
|
||||
public void applyFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
|
||||
final PsiMethodCallExpression callExpression = (PsiMethodCallExpression) methodNameIdentifier.getParent().getParent();
|
||||
final PsiReferenceExpression methodExpression = callExpression.getMethodExpression();
|
||||
|
||||
final PsiMethod method = (PsiMethod) methodExpression.resolve();
|
||||
final PsiParameterList paramList = method.getParameterList();
|
||||
final PsiParameter[] parameters = paramList.getParameters();
|
||||
final PsiManager psiManager = callExpression.getManager();
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
final PsiType stringType = PsiType.getJavaLangString(psiManager, scope);
|
||||
final PsiType paramType1 = parameters[0].getType();
|
||||
final int expectedPosition;
|
||||
final int actualPosition;
|
||||
if (paramType1.equals(stringType) && parameters.length > 2) {
|
||||
expectedPosition = 1;
|
||||
actualPosition = 2;
|
||||
} else {
|
||||
expectedPosition = 0;
|
||||
actualPosition = 1;
|
||||
}
|
||||
final PsiExpressionList argumentList = callExpression.getArgumentList();
|
||||
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiExpression expectedArg = args[expectedPosition];
|
||||
final PsiExpression actualArg = args[actualPosition];
|
||||
final String actualArgText = actualArg.getText();
|
||||
final String expectedArgText = expectedArg.getText();
|
||||
replaceExpression(project, expectedArg, actualArgText);
|
||||
replaceExpression(project, actualArg, expectedArgText);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new MisorderedAssertEqualsParametersVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class MisorderedAssertEqualsParametersVisitor extends BaseInspectionVisitor {
|
||||
|
||||
private MisorderedAssertEqualsParametersVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
super.visitMethodCallExpression(expression);
|
||||
if (!isAssertEquals(expression)) {
|
||||
return;
|
||||
}
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
|
||||
final PsiMethod method = (PsiMethod) methodExpression.resolve();
|
||||
final PsiParameterList paramList = method.getParameterList();
|
||||
if (paramList == null) {
|
||||
return;
|
||||
}
|
||||
final PsiParameter[] parameters = paramList.getParameters();
|
||||
|
||||
final PsiManager psiManager = expression.getManager();
|
||||
|
||||
final Project project = psiManager.getProject();
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
final PsiType stringType = PsiType.getJavaLangString(psiManager, scope);
|
||||
final PsiType paramType1 = parameters[0].getType();
|
||||
final int expectedPosition;
|
||||
final int actualPosition ;
|
||||
if (paramType1.equals(stringType)&& parameters.length > 2) {
|
||||
expectedPosition = 1;
|
||||
actualPosition = 2;
|
||||
} else {
|
||||
expectedPosition = 0;
|
||||
actualPosition = 1;
|
||||
}
|
||||
final PsiExpressionList argumentList = expression.getArgumentList();
|
||||
if(argumentList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiExpression expectedArg = args[expectedPosition];
|
||||
final PsiExpression actualArg = args[actualPosition];
|
||||
if(expectedArg == null || actualArg == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(expectedArg instanceof PsiLiteralExpression)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!(actualArg instanceof PsiLiteralExpression))
|
||||
{
|
||||
return;
|
||||
}
|
||||
registerMethodCallError(expression);
|
||||
}
|
||||
|
||||
private static boolean isAssertEquals(PsiMethodCallExpression expression) {
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if (!"assertEquals".equals(methodName)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethod method = (PsiMethod) methodExpression.resolve();
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiClass targetClass = method.getContainingClass();
|
||||
if (!ClassUtils.isSubclass(targetClass, "junit.framework.Assert")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
package com.siyeh.ig.junit;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.siyeh.ig.*;
|
||||
import com.siyeh.ig.psiutils.ClassUtils;
|
||||
|
||||
public class SimplifiableJUnitAssertionInspection extends ExpressionInspection {
|
||||
private SimplifyJUnitAssertFix fix = new SimplifyJUnitAssertFix();
|
||||
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Simplifiable JUnit assertion";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.JUNIT_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "#ref() can be simplified to assertEquals() #loc";
|
||||
}
|
||||
|
||||
public InspectionGadgetsFix buildFix(PsiElement location) {
|
||||
return fix;
|
||||
}
|
||||
|
||||
private static class SimplifyJUnitAssertFix extends InspectionGadgetsFix {
|
||||
public String getName() {
|
||||
return "Simplify assertion";
|
||||
}
|
||||
|
||||
public void applyFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement methodNameIdentifier = descriptor.getPsiElement();
|
||||
final PsiMethodCallExpression callExpression = (PsiMethodCallExpression) methodNameIdentifier.getParent().getParent();
|
||||
final PsiReferenceExpression methodExpression = callExpression.getMethodExpression();
|
||||
|
||||
final PsiMethod method = (PsiMethod) methodExpression.resolve();
|
||||
final PsiParameterList paramList = method.getParameterList();
|
||||
final PsiParameter[] parameters = paramList.getParameters();
|
||||
|
||||
final PsiManager psiManager = callExpression.getManager();
|
||||
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
final PsiType stringType = PsiType.getJavaLangString(psiManager, scope);
|
||||
final PsiType paramType1 = parameters[0].getType();
|
||||
final PsiExpressionList argumentList = callExpression.getArgumentList();
|
||||
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final int testPosition;
|
||||
final PsiExpression message;
|
||||
if (paramType1.equals(stringType) && parameters.length > 2) {
|
||||
testPosition = 1;
|
||||
message = args[0];
|
||||
} else {
|
||||
testPosition = 0;
|
||||
message = null;
|
||||
}
|
||||
final PsiExpression testArg = args[testPosition];
|
||||
|
||||
PsiExpression lhs = null;
|
||||
PsiExpression rhs = null;
|
||||
if (testArg instanceof PsiBinaryExpression) {
|
||||
lhs = ((PsiBinaryExpression) testArg).getLOperand();
|
||||
rhs = ((PsiBinaryExpression) testArg).getROperand();
|
||||
} else if (testArg instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression call = (PsiMethodCallExpression) testArg;
|
||||
final PsiReferenceExpression equalityMethodExpression = call.getMethodExpression();
|
||||
final PsiExpressionList equalityArgumentList = call.getArgumentList();
|
||||
final PsiExpression[] equalityArgs = equalityArgumentList.getExpressions();
|
||||
rhs = equalityArgs[0];
|
||||
lhs = equalityMethodExpression.getQualifierExpression();
|
||||
}
|
||||
if(!(lhs instanceof PsiLiteralExpression) &&
|
||||
rhs instanceof PsiLiteralExpression)
|
||||
{
|
||||
final PsiExpression temp = lhs;
|
||||
lhs = rhs;
|
||||
rhs = temp;
|
||||
}
|
||||
final StringBuffer newExpression = new StringBuffer("assertEquals(");
|
||||
if(message!=null)
|
||||
{
|
||||
newExpression.append(message.getText());
|
||||
newExpression.append(',');
|
||||
}
|
||||
newExpression.append(lhs.getText());
|
||||
newExpression.append(',');
|
||||
newExpression.append(rhs.getText());
|
||||
if(isFloatingPoint(lhs) || isFloatingPoint(rhs))
|
||||
{
|
||||
newExpression.append(",0.0");
|
||||
}
|
||||
newExpression.append(')');
|
||||
replaceExpression(project, callExpression, newExpression.toString());
|
||||
}
|
||||
|
||||
private boolean isFloatingPoint(PsiExpression expression) {
|
||||
final PsiType type = expression.getType();
|
||||
return PsiType.FLOAT.equals(type)|| PsiType.DOUBLE.equals(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new MisorderedAssertEqualsParametersVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class MisorderedAssertEqualsParametersVisitor extends BaseInspectionVisitor {
|
||||
|
||||
private MisorderedAssertEqualsParametersVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
super.visitMethodCallExpression(expression);
|
||||
if (!isAssertTrue(expression)) {
|
||||
return;
|
||||
}
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
|
||||
final PsiMethod method = (PsiMethod) methodExpression.resolve();
|
||||
final PsiParameterList paramList = method.getParameterList();
|
||||
if (paramList == null) {
|
||||
return;
|
||||
}
|
||||
final PsiParameter[] parameters = paramList.getParameters();
|
||||
|
||||
final PsiManager psiManager = expression.getManager();
|
||||
|
||||
final Project project = psiManager.getProject();
|
||||
final GlobalSearchScope scope = GlobalSearchScope.allScope(project);
|
||||
final PsiType stringType = PsiType.getJavaLangString(psiManager, scope);
|
||||
final PsiType paramType1 = parameters[0].getType();
|
||||
final int testPosition;
|
||||
if (paramType1.equals(stringType) && parameters.length > 1) {
|
||||
testPosition = 1;
|
||||
} else {
|
||||
testPosition = 0;
|
||||
}
|
||||
final PsiExpressionList argumentList = expression.getArgumentList();
|
||||
if (argumentList == null) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
final PsiExpression testArg = args[testPosition];
|
||||
if (testArg == null) {
|
||||
return;
|
||||
}
|
||||
if (!isEqualityComparison(testArg)) {
|
||||
return;
|
||||
}
|
||||
registerMethodCallError(expression);
|
||||
}
|
||||
|
||||
private boolean isEqualityComparison(PsiExpression testArg) {
|
||||
if (testArg instanceof PsiBinaryExpression) {
|
||||
final PsiJavaToken sign = ((PsiBinaryExpression) testArg).getOperationSign();
|
||||
if(sign == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!sign.getTokenType().equals(JavaTokenType.EQEQ))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final PsiExpression lhs = ((PsiBinaryExpression) testArg).getLOperand();
|
||||
if(lhs == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final PsiExpression rhs = ((PsiBinaryExpression) testArg).getROperand();
|
||||
if(rhs == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final PsiType type = lhs.getType();
|
||||
if(type == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!ClassUtils.isPrimitive(type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else if (testArg instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression call = (PsiMethodCallExpression) testArg;
|
||||
final PsiReferenceExpression methodExpression = call.getMethodExpression();
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if(!"equals".equals(methodName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final PsiExpressionList argumentList = call.getArgumentList();
|
||||
if(argumentList == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final PsiExpression[] args = argumentList.getExpressions();
|
||||
if(args == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(args.length!=1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(args[0] == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(methodExpression.getQualifierExpression() == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isAssertTrue(PsiMethodCallExpression expression) {
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if (!"assertTrue".equals(methodName)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethod method = (PsiMethod) methodExpression.resolve();
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiClass targetClass = method.getContainingClass();
|
||||
if (!ClassUtils.isSubclass(targetClass, "junit.framework.Assert")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.siyeh.ig.junit;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.psiutils.ClassUtils;
|
||||
import com.siyeh.ig.psiutils.TestUtils;
|
||||
import com.siyeh.ig.fixes.MoveClassFix;
|
||||
import com.siyeh.ig.*;
|
||||
|
||||
public class TestCaseInProductCodeInspection extends ClassInspection {
|
||||
private final MoveClassFix fix = new MoveClassFix();
|
||||
|
||||
public String getDisplayName() {
|
||||
return "JUnit TestCase in product source";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.JUNIT_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Test case #ref should probably be placed in a test source tree #loc";
|
||||
}
|
||||
|
||||
protected InspectionGadgetsFix buildFix(PsiElement location) {
|
||||
return fix;
|
||||
}
|
||||
|
||||
protected boolean buildQuickFixesOnlyForOnTheFlyErrors() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new TestCaseInProductCodeVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class TestCaseInProductCodeVisitor extends BaseInspectionVisitor {
|
||||
|
||||
private TestCaseInProductCodeVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitClass(PsiClass aClass) {
|
||||
if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) {
|
||||
return;
|
||||
}
|
||||
if(TestUtils.isTest(aClass))
|
||||
{
|
||||
return;
|
||||
}
|
||||
registerClassError(aClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.siyeh.ig.junit;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ClassInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import com.siyeh.ig.psiutils.ClassUtils;
|
||||
|
||||
public class UnconstructableTestCaseInspection extends ClassInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Unconstructable JUnit TestCase";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.JUNIT_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Test case #ref is unusable by most test runners #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new UnconstructableTestCaseVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class UnconstructableTestCaseVisitor extends BaseInspectionVisitor {
|
||||
|
||||
private UnconstructableTestCaseVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitClass(PsiClass aClass) {
|
||||
if (aClass.isInterface() || aClass.isEnum() || aClass.isAnnotationType() ||
|
||||
aClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
return;
|
||||
}
|
||||
if (!ClassUtils.isSubclass(aClass, "junit.framework.TestCase")) {
|
||||
return;
|
||||
}
|
||||
boolean hasConstructor = false;
|
||||
boolean hasNoArgConstructor = false;
|
||||
boolean hasStringConstructor = false;
|
||||
|
||||
final PsiMethod[] constructors = aClass.getConstructors();
|
||||
if (constructors == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < constructors.length; i++) {
|
||||
final PsiMethod constructor = constructors[i];
|
||||
hasConstructor = true;
|
||||
if (!constructor.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
continue;
|
||||
}
|
||||
final PsiParameterList parameterList = constructor.getParameterList();
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
if (parameters.length == 0) {
|
||||
hasNoArgConstructor = true;
|
||||
}
|
||||
if (parameters.length == 1) {
|
||||
final PsiType type = parameters[0].getType();
|
||||
if (type != null) {
|
||||
if (type.getCanonicalText().equals("java.lang.String")) {
|
||||
hasStringConstructor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasConstructor) {
|
||||
return;
|
||||
}
|
||||
if (hasNoArgConstructor || hasStringConstructor) {
|
||||
return;
|
||||
}
|
||||
registerClassError(aClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
package com.siyeh.ig.naming;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiParameter;
|
||||
import com.intellij.psi.PsiParameterList;
|
||||
import com.intellij.psi.util.PsiSuperMethodUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.*;
|
||||
import com.siyeh.ig.fixes.RenameFix;
|
||||
|
||||
public class ParameterNameDiffersFromOverriddenParameterInspection extends MethodInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Parameter name differs from parameter in overridden method";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.NAMING_CONVENTIONS_GROUP_NAME;
|
||||
}
|
||||
|
||||
protected InspectionGadgetsFix buildFix(PsiElement location) {
|
||||
final PsiParameter parameter = (PsiParameter) location.getParent();
|
||||
final String parameterName = parameter.getName();
|
||||
final PsiMethod method = (PsiMethod) PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
|
||||
final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method);
|
||||
final int index = method.getParameterList().getParameterIndex(parameter);
|
||||
String name = "";
|
||||
for (int i = 0; i < superMethods.length; i++) {
|
||||
final PsiMethod superMethod = superMethods[i];
|
||||
final PsiParameterList parameterList = superMethod.getParameterList();
|
||||
if (parameterList != null) {
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
if (parameters != null) {
|
||||
final String superParameterName = parameters[index].getName();
|
||||
if (superParameterName != null && !superParameterName.equals(parameterName)) {
|
||||
name = superParameterName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new RenameFix(name);
|
||||
}
|
||||
|
||||
protected boolean buildQuickFixesOnlyForOnTheFlyErrors() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
final PsiParameter parameter = (PsiParameter) location.getParent();
|
||||
final String parameterName = parameter.getName();
|
||||
final PsiMethod method = (PsiMethod) PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
|
||||
final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method);
|
||||
final int index = method.getParameterList().getParameterIndex(parameter);
|
||||
String name = "";
|
||||
for (int i = 0; i < superMethods.length; i++) {
|
||||
final PsiMethod superMethod = superMethods[i];
|
||||
final PsiParameterList parameterList = superMethod.getParameterList();
|
||||
if (parameterList != null) {
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
if (parameters != null) {
|
||||
final String superParameterName = parameters[index].getName();
|
||||
if (superParameterName != null && !superParameterName.equals(parameterName)) {
|
||||
name = superParameterName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "Parameter name '#ref' is different from parameter '" + name + "'overridden #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new ParameterNameDiffersFromOverriddenParameterVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class ParameterNameDiffersFromOverriddenParameterVisitor extends BaseInspectionVisitor {
|
||||
private ParameterNameDiffersFromOverriddenParameterVisitor(BaseInspection inspection,
|
||||
InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitMethod(PsiMethod method) {
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
if (parameterList == null) {
|
||||
return;
|
||||
}
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
if (parameters == null || parameters.length == 0) {
|
||||
return;
|
||||
}
|
||||
final PsiMethod[] superMethods = PsiSuperMethodUtil.findSuperMethods(method);
|
||||
if (superMethods == null || superMethods.length == 0) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
checkParameter(parameters[i], i, superMethods);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkParameter(PsiParameter parameter, int index, PsiMethod[] superMethods) {
|
||||
final String parameterName = parameter.getName();
|
||||
if(parameterName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < superMethods.length; i++) {
|
||||
final PsiMethod superMethod = superMethods[i];
|
||||
final PsiParameterList parameterList = superMethod.getParameterList();
|
||||
if (parameterList != null) {
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
if (parameters != null) {
|
||||
final String superParameterName = parameters[index].getName();
|
||||
if (superParameterName!=null &&!superParameterName.equals(parameterName)) {
|
||||
registerVariableError(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.siyeh.ig.performance;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.FieldInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
|
||||
public class StringBufferFieldInspection extends FieldInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "StringBuffer field";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.PERFORMANCE_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
final PsiField field = (PsiField) location.getParent();
|
||||
final PsiType type = field.getType();
|
||||
final String typeName = type.getPresentableText();
|
||||
return typeName+ " field '#ref' #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new StringBufferFieldVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class StringBufferFieldVisitor extends BaseInspectionVisitor {
|
||||
private StringBufferFieldVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitField(PsiField field) {
|
||||
super.visitField(field);
|
||||
final PsiType type = field.getType();
|
||||
if(type == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final String text = type.getCanonicalText();
|
||||
if (!"java.lang.StringBuffer".equals(text) &&
|
||||
!"java.lang.StringBuilder".equals(text)) {
|
||||
return;
|
||||
}
|
||||
registerFieldError(field);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
|
||||
public class TestUtils {
|
||||
private TestUtils() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static boolean isTest(PsiClass aClass) {
|
||||
final PsiManager manager = aClass.getManager();
|
||||
final PsiFile file = (PsiFile) PsiTreeUtil.getParentOfType(aClass,
|
||||
PsiFile.class);
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
final Project project = manager.getProject();
|
||||
return TestUtils.isTest(project, virtualFile);
|
||||
}
|
||||
|
||||
public static boolean isTest(PsiDirectory directory) {
|
||||
final PsiManager manager = directory.getManager();
|
||||
final VirtualFile virtualFile = directory.getVirtualFile();
|
||||
final Project project = manager.getProject();
|
||||
return TestUtils.isTest(project, virtualFile);
|
||||
}
|
||||
|
||||
public static boolean isTest(Project project, VirtualFile virtualFile) {
|
||||
if (virtualFile == null) {
|
||||
return false;
|
||||
}
|
||||
final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
|
||||
final ProjectFileIndex fileIndex = rootManager.getFileIndex();
|
||||
return fileIndex.isInTestSourceContent(virtualFile);
|
||||
}
|
||||
|
||||
public static boolean isTest(PsiJavaFile file) {
|
||||
final PsiManager manager = file.getManager();
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
final Project project = manager.getProject();
|
||||
return TestUtils.isTest(project, virtualFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
|
||||
public class VariableUsedVisitor extends PsiRecursiveElementVisitor {
|
||||
private boolean used = false;
|
||||
private final PsiVariable variable;
|
||||
|
||||
public VariableUsedVisitor(PsiVariable variable) {
|
||||
super();
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
public void visitReferenceExpression(PsiReferenceExpression ref) {
|
||||
final PsiExpression qualifier = ref.getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
qualifier.accept(this);
|
||||
}
|
||||
final PsiReferenceParameterList typeParameters = ref.getParameterList();
|
||||
if (typeParameters != null) {
|
||||
typeParameters.accept(this);
|
||||
}
|
||||
final PsiElement referent = ref.resolve();
|
||||
if (referent == null) {
|
||||
return;
|
||||
}
|
||||
if (referent.equals(variable)) {
|
||||
used = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUsed() {
|
||||
return used;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
package com.siyeh.ig.resources;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ExpressionInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
|
||||
public class IOResourceInspection extends ExpressionInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "I/O resource opened but not safely closed";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.RESOURCE_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
final PsiExpression expression = (PsiExpression) location;
|
||||
final PsiType type = expression.getType();
|
||||
final String text = type.getPresentableText();
|
||||
return text + " should be opened in a try block, and closed in a finally block #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new IOResourceVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class IOResourceVisitor extends BaseInspectionVisitor {
|
||||
private IOResourceVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
super.visitNewExpression(expression);
|
||||
if (!isIOResource(expression)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement parent = expression.getParent();
|
||||
if(parent instanceof PsiExpressionList)
|
||||
{
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if(grandParent instanceof PsiNewExpression &&
|
||||
isIOResource((PsiNewExpression) grandParent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!(parent instanceof PsiAssignmentExpression)) {
|
||||
registerError(expression);
|
||||
return;
|
||||
}
|
||||
final PsiAssignmentExpression assignment = (PsiAssignmentExpression) parent;
|
||||
final PsiExpression lhs = assignment.getLExpression();
|
||||
if(!(lhs instanceof PsiReferenceExpression))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) lhs).resolve();
|
||||
if(referent == null || !(referent instanceof PsiVariable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiVariable boundVariable = (PsiVariable) referent;
|
||||
final PsiElement containingBlock = PsiTreeUtil.getParentOfType(expression, PsiCodeBlock.class);
|
||||
|
||||
if(isArgToResourceCreation(boundVariable, containingBlock))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PsiElement currentContext = expression;
|
||||
while (true) {
|
||||
final PsiTryStatement tryStatement =
|
||||
(PsiTryStatement) PsiTreeUtil.getParentOfType(currentContext, PsiTryStatement.class);
|
||||
if (tryStatement == null) {
|
||||
registerError(expression);
|
||||
return;
|
||||
}
|
||||
if (resourceIsOpenedInTryAndClosedInFinally(tryStatement, expression, boundVariable)) {
|
||||
return;
|
||||
}
|
||||
currentContext = tryStatement;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isArgToResourceCreation(PsiVariable boundVariable, PsiElement scope) {
|
||||
final UsedAsIOResourceArgVisitor visitor = new UsedAsIOResourceArgVisitor(boundVariable);
|
||||
scope.accept(visitor);
|
||||
return visitor.usedAsArgToResourceCreation();
|
||||
}
|
||||
|
||||
private static boolean resourceIsOpenedInTryAndClosedInFinally(PsiTryStatement tryStatement,
|
||||
PsiExpression lhs, PsiVariable boundVariable) {
|
||||
final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
|
||||
if (finallyBlock == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
|
||||
if (tryBlock == null) {
|
||||
return false;
|
||||
}
|
||||
if (!PsiTreeUtil.isAncestor(tryBlock, lhs, true)) {
|
||||
return false;
|
||||
}
|
||||
return containsResourceClose(finallyBlock, boundVariable);
|
||||
}
|
||||
|
||||
private static boolean containsResourceClose(PsiCodeBlock finallyBlock, PsiVariable boundVariable) {
|
||||
final StreamCloseVisitor visitor = new StreamCloseVisitor(boundVariable);
|
||||
finallyBlock.accept(visitor);
|
||||
return visitor.containsStreamClose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class StreamCloseVisitor extends PsiRecursiveElementVisitor {
|
||||
private boolean containsStreamClose = false;
|
||||
private PsiVariable streamToClose;
|
||||
|
||||
private StreamCloseVisitor(PsiVariable streamToClose) {
|
||||
super();
|
||||
this.streamToClose = streamToClose;
|
||||
}
|
||||
|
||||
public void visitReferenceExpression(PsiReferenceExpression ref) {
|
||||
final PsiExpression qualifier = ref.getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
qualifier.accept(this);
|
||||
}
|
||||
final PsiReferenceParameterList typeParameters = ref.getParameterList();
|
||||
if (typeParameters != null) {
|
||||
typeParameters.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression call) {
|
||||
super.visitMethodCallExpression(call);
|
||||
final PsiReferenceExpression methodExpression = call.getMethodExpression();
|
||||
if (methodExpression == null) {
|
||||
return;
|
||||
}
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if (!"close".equals(methodName)) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (qualifier == null) {
|
||||
return;
|
||||
}
|
||||
if(!(qualifier instanceof PsiReferenceExpression))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) qualifier).resolve();
|
||||
if (referent.equals(streamToClose)) {
|
||||
containsStreamClose = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsStreamClose() {
|
||||
return containsStreamClose;
|
||||
}
|
||||
}
|
||||
|
||||
private static class UsedAsIOResourceArgVisitor extends PsiRecursiveElementVisitor {
|
||||
private boolean usedAsArgToResourceCreation = false;
|
||||
private PsiVariable ioResource;
|
||||
|
||||
private UsedAsIOResourceArgVisitor(PsiVariable streamToClose) {
|
||||
super();
|
||||
this.ioResource = streamToClose;
|
||||
}
|
||||
|
||||
public void visitReferenceExpression(PsiReferenceExpression ref) {
|
||||
final PsiExpression qualifier = ref.getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
qualifier.accept(this);
|
||||
}
|
||||
final PsiReferenceParameterList typeParameters = ref.getParameterList();
|
||||
if (typeParameters != null) {
|
||||
typeParameters.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
super.visitNewExpression(expression);
|
||||
if(!isIOResource(expression))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiExpressionList argList = expression.getArgumentList();
|
||||
if(argList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiExpression[] expressions = argList.getExpressions();
|
||||
if(expressions == null || expressions.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiExpression arg = expressions[0];
|
||||
if(arg == null || !(arg instanceof PsiReferenceExpression))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) arg).resolve();
|
||||
if(referent ==null || !referent.equals(ioResource))
|
||||
{
|
||||
return;
|
||||
}
|
||||
usedAsArgToResourceCreation = true;
|
||||
}
|
||||
|
||||
public boolean usedAsArgToResourceCreation() {
|
||||
return usedAsArgToResourceCreation;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isIOResource(PsiNewExpression expression) {
|
||||
return TypeUtils.expressionHasTypeOrSubtype("java.io.InputStream", expression) ||
|
||||
TypeUtils.expressionHasTypeOrSubtype("java.io.Writer", expression) ||
|
||||
TypeUtils.expressionHasTypeOrSubtype("java.io.Reader", expression) ||
|
||||
TypeUtils.expressionHasTypeOrSubtype("java.io.RandomAccessFile", expression) ||
|
||||
TypeUtils.expressionHasTypeOrSubtype("java.io.OutputStream", expression);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.siyeh.ig.resources;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ExpressionInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
|
||||
public class JDBCResourceInspection extends ExpressionInspection {
|
||||
private static String[] creationMethodClassName =
|
||||
new String[]{
|
||||
"java.sql.Driver",
|
||||
"java.sql.DriverManager",
|
||||
"java.sql.Connection",
|
||||
"java.sql.Connection",
|
||||
"java.sql.Connection",
|
||||
"java.sql.Statement",
|
||||
"java.sql.Statement",
|
||||
};
|
||||
private static String[] creationMethodName =
|
||||
new String[]{
|
||||
"connect",
|
||||
"getConnection",
|
||||
"createStatement",
|
||||
"prepareStatement",
|
||||
"prepareCall",
|
||||
"executeQuery",
|
||||
"getResultSet",
|
||||
};
|
||||
|
||||
public String getDisplayName() {
|
||||
return "JDBC resource opened but not safely closed";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.RESOURCE_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
final PsiExpression expression = (PsiExpression) location;
|
||||
final PsiType type = expression.getType();
|
||||
final String text = type.getPresentableText();
|
||||
return "JDBC " + text + " should be opened in a try block, and closed in a finally block #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new JDBCResourceVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class JDBCResourceVisitor extends BaseInspectionVisitor {
|
||||
private JDBCResourceVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
super.visitMethodCallExpression(expression);
|
||||
if (!isJDBCResourceCreation(expression)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (!(parent instanceof PsiAssignmentExpression)) {
|
||||
registerError(expression);
|
||||
return;
|
||||
}
|
||||
final PsiAssignmentExpression assignment = (PsiAssignmentExpression) parent;
|
||||
final PsiExpression lhs = assignment.getLExpression();
|
||||
if (!(lhs instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) lhs).resolve();
|
||||
if (referent == null || !(referent instanceof PsiVariable)) {
|
||||
return;
|
||||
}
|
||||
final PsiVariable boundVariable = (PsiVariable) referent;
|
||||
|
||||
PsiElement currentContext = expression;
|
||||
while (true) {
|
||||
final PsiTryStatement tryStatement =
|
||||
(PsiTryStatement) PsiTreeUtil.getParentOfType(currentContext, PsiTryStatement.class);
|
||||
if (tryStatement == null) {
|
||||
registerError(expression);
|
||||
return;
|
||||
}
|
||||
if (resourceIsOpenedInTryAndClosedInFinally(tryStatement, expression, boundVariable)) {
|
||||
return;
|
||||
}
|
||||
currentContext = tryStatement;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static boolean resourceIsOpenedInTryAndClosedInFinally(PsiTryStatement tryStatement,
|
||||
PsiExpression lhs, PsiVariable boundVariable) {
|
||||
final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
|
||||
if (finallyBlock == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
|
||||
if (tryBlock == null) {
|
||||
return false;
|
||||
}
|
||||
if (!PsiTreeUtil.isAncestor(tryBlock, lhs, true)) {
|
||||
return false;
|
||||
}
|
||||
return containsResourceClose(finallyBlock, boundVariable);
|
||||
}
|
||||
|
||||
private static boolean containsResourceClose(PsiCodeBlock finallyBlock, PsiVariable boundVariable) {
|
||||
final ResourceCloseVisitor visitor = new ResourceCloseVisitor(boundVariable);
|
||||
finallyBlock.accept(visitor);
|
||||
return visitor.containsResourceClose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ResourceCloseVisitor extends PsiRecursiveElementVisitor {
|
||||
private boolean containsResourceClose = false;
|
||||
private PsiVariable streamToClose;
|
||||
|
||||
private ResourceCloseVisitor(PsiVariable streamToClose) {
|
||||
super();
|
||||
this.streamToClose = streamToClose;
|
||||
}
|
||||
|
||||
public void visitReferenceExpression(PsiReferenceExpression ref) {
|
||||
final PsiExpression qualifier = ref.getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
qualifier.accept(this);
|
||||
}
|
||||
final PsiReferenceParameterList typeParameters = ref.getParameterList();
|
||||
if (typeParameters != null) {
|
||||
typeParameters.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression call) {
|
||||
super.visitMethodCallExpression(call);
|
||||
final PsiReferenceExpression methodExpression = call.getMethodExpression();
|
||||
if (methodExpression == null) {
|
||||
return;
|
||||
}
|
||||
final String methodName = methodExpression.getReferenceName();
|
||||
if (!"close".equals(methodName)) {
|
||||
return;
|
||||
}
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (qualifier == null) {
|
||||
return;
|
||||
}
|
||||
if (!(qualifier instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) qualifier).resolve();
|
||||
if (referent.equals(streamToClose)) {
|
||||
containsResourceClose = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsResourceClose() {
|
||||
return containsResourceClose;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isJDBCResourceCreation(PsiMethodCallExpression expression) {
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
final String name = method.getName();
|
||||
if (containingClass == null) {
|
||||
return false;
|
||||
}
|
||||
final String className = containingClass.getQualifiedName();
|
||||
for (int i = 0; i < creationMethodName.length; i++) {
|
||||
if (name.equals(creationMethodName[i]) &&
|
||||
className.equals(creationMethodClassName[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.siyeh.ig.serialization;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.ClassInspection;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import com.siyeh.ig.psiutils.SerializationUtils;
|
||||
|
||||
public class SerialPersistentFieldsWithWrongSignatureInspection extends ClassInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "'serialPersistentFields' field not declared 'private static final ObjectStreamField[]'";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.SERIALIZATION_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "#ref field of a Serializable class is not declared 'private static final ObjectStreamField[]' #loc ";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new SerializableDefinesSerialVersionUIDVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class SerializableDefinesSerialVersionUIDVisitor extends BaseInspectionVisitor {
|
||||
private SerializableDefinesSerialVersionUIDVisitor(BaseInspection inspection,
|
||||
InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitClass(PsiClass aClass) {
|
||||
// no call to super, so it doesn't drill down
|
||||
if (aClass.isInterface() || aClass.isAnnotationType()) {
|
||||
return;
|
||||
}
|
||||
if (!SerializationUtils.isSerializable(aClass)) {
|
||||
return;
|
||||
}
|
||||
final PsiField[] fields = aClass.getFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
final PsiField field = fields[i];
|
||||
if (isSerialPersistentFields(field)) {
|
||||
if (!field.hasModifierProperty(PsiModifier.PRIVATE) ||
|
||||
!field.hasModifierProperty(PsiModifier.STATIC) ||
|
||||
!field.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
registerFieldError(field);
|
||||
} else {
|
||||
final PsiType type = field.getType();
|
||||
if (type != null) {
|
||||
final String text = type.getCanonicalText();
|
||||
if (!text.equals("java.io.ObjectStreamField[]")) {
|
||||
registerFieldError(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSerialPersistentFields(PsiField field) {
|
||||
final String fieldName = field.getName();
|
||||
return "serialPersistentFields".equals(fieldName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.siyeh.ig.threading;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.GroupNames;
|
||||
import com.siyeh.ig.StatementInspection;
|
||||
|
||||
public class CallToNativeMethodWhileLockedInspection extends StatementInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Call to a native method while locked";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.THREADING_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Call to native method #ref() in a synchronized context #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new WaitNotInSynchronizedContextVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
private static class WaitNotInSynchronizedContextVisitor extends BaseInspectionVisitor {
|
||||
private boolean m_inSynchronizedContext = false;
|
||||
|
||||
private WaitNotInSynchronizedContextVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
super.visitMethodCallExpression(expression);
|
||||
if (!m_inSynchronizedContext) {
|
||||
return;
|
||||
}
|
||||
final PsiMethod method = expression.resolveMethod();
|
||||
if(method == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!method.hasModifierProperty(PsiModifier.NATIVE)) {
|
||||
return;
|
||||
}
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if(containingClass == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final String className = containingClass.getQualifiedName();
|
||||
if("java.lang.Object".equals(className))
|
||||
{
|
||||
return;
|
||||
}
|
||||
registerMethodCallError(expression);
|
||||
}
|
||||
|
||||
public void visitMethod(PsiMethod method) {
|
||||
final boolean wasInSynchronizedContext = m_inSynchronizedContext;
|
||||
if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
|
||||
|
||||
m_inSynchronizedContext = true;
|
||||
}
|
||||
super.visitMethod(method);
|
||||
if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
|
||||
|
||||
m_inSynchronizedContext = wasInSynchronizedContext;
|
||||
}
|
||||
}
|
||||
|
||||
public void visitSynchronizedStatement(PsiSynchronizedStatement psiSynchronizedStatement) {
|
||||
final boolean wasInSynchronizedContext = m_inSynchronizedContext;
|
||||
m_inSynchronizedContext = true;
|
||||
super.visitSynchronizedStatement(psiSynchronizedStatement);
|
||||
m_inSynchronizedContext = wasInSynchronizedContext;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package com.siyeh.ig.verbose;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.*;
|
||||
|
||||
public class UnnecessaryConstructorInspection extends ClassInspection {
|
||||
private final UnnecessaryConstructorFix fix = new UnnecessaryConstructorFix();
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Redundant no-arg constructor";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.VERBOSE_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "No-arg constructor #ref is unnecessary #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new UnnecessaryConstructorVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
public InspectionGadgetsFix buildFix(PsiElement location) {
|
||||
return fix;
|
||||
}
|
||||
|
||||
private static class UnnecessaryConstructorFix extends InspectionGadgetsFix {
|
||||
public String getName() {
|
||||
return "Remove redundant constructor";
|
||||
}
|
||||
|
||||
public void applyFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement nameIdentifier = descriptor.getPsiElement();
|
||||
final PsiElement constructor = nameIdentifier.getParent();
|
||||
deleteElement(constructor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class UnnecessaryConstructorVisitor extends BaseInspectionVisitor {
|
||||
private UnnecessaryConstructorVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitClass(PsiClass aClass) {
|
||||
|
||||
final PsiMethod[] constructors = aClass.getConstructors();
|
||||
if (constructors == null) {
|
||||
return;
|
||||
}
|
||||
if (constructors.length != 1) {
|
||||
return;
|
||||
}
|
||||
final PsiMethod constructor = constructors[0];
|
||||
if (!constructor.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
return;
|
||||
}
|
||||
final PsiParameterList parameterList = constructor.getParameterList();
|
||||
if (parameterList == null) {
|
||||
return;
|
||||
}
|
||||
if (parameterList.getParameters().length != 0) {
|
||||
return;
|
||||
}
|
||||
final PsiCodeBlock body = constructor.getBody();
|
||||
if (body == null) {
|
||||
return;
|
||||
}
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
if (statements == null) {
|
||||
return;
|
||||
}
|
||||
if (statements.length == 0) {
|
||||
registerMethodError(constructor);
|
||||
}else if(statements.length == 1)
|
||||
{
|
||||
final PsiStatement statement = statements[0];
|
||||
if("super();".equals(statement.getText()))
|
||||
{
|
||||
registerMethodError(constructor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
package com.siyeh.ig.verbose;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.*;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import com.siyeh.ig.fixes.InlineVariableFix;
|
||||
|
||||
public class UnnecessaryLocalVariableInspection extends StatementInspection {
|
||||
|
||||
public String getDisplayName() {
|
||||
return "Redundant local variable";
|
||||
}
|
||||
|
||||
public String getGroupDisplayName() {
|
||||
return GroupNames.VERBOSE_GROUP_NAME;
|
||||
}
|
||||
|
||||
public String buildErrorString(PsiElement location) {
|
||||
return "Local variable #ref is redundant #loc";
|
||||
}
|
||||
|
||||
public BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) {
|
||||
return new UnnecessaryLocalVariableVisitor(this, inspectionManager, onTheFly);
|
||||
}
|
||||
|
||||
public InspectionGadgetsFix buildFix(PsiElement location) {
|
||||
return new InlineVariableFix();
|
||||
}
|
||||
|
||||
private static class UnnecessaryLocalVariableVisitor extends BaseInspectionVisitor {
|
||||
private UnnecessaryLocalVariableVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) {
|
||||
super(inspection, inspectionManager, isOnTheFly);
|
||||
}
|
||||
|
||||
public void visitLocalVariable(PsiLocalVariable variable) {
|
||||
super.visitLocalVariable(variable);
|
||||
if (isCopyVariable(variable)) {
|
||||
registerVariableError(variable);
|
||||
} else if (isImmediatelyReturned(variable)) {
|
||||
registerVariableError(variable);
|
||||
} else if (isImmediatelyAssigned(variable)) {
|
||||
registerVariableError(variable);
|
||||
}else if (isImmediatelyAssignedAsDeclaration(variable)) {
|
||||
registerVariableError(variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCopyVariable(PsiVariable variable) {
|
||||
final PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(initializer instanceof PsiReferenceExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement referent = ((PsiReference) initializer).resolve();
|
||||
if (referent == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(referent instanceof PsiLocalVariable || referent instanceof PsiParameter)) {
|
||||
return false;
|
||||
}
|
||||
final PsiCodeBlock containingScope =
|
||||
(PsiCodeBlock) PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
|
||||
if (containingScope == null) {
|
||||
return false;
|
||||
}
|
||||
final VariableAssignedVisitor visitor = new VariableAssignedVisitor(variable);
|
||||
containingScope.accept(visitor);
|
||||
if (visitor.isAssigned()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiVariable initialization = (PsiVariable) referent;
|
||||
final VariableAssignedVisitor visitor2 = new VariableAssignedVisitor(variable);
|
||||
containingScope.accept(visitor2);
|
||||
if (visitor2.isAssigned()) {
|
||||
return false;
|
||||
}
|
||||
if (!initialization.hasModifierProperty(PsiModifier.FINAL)
|
||||
&& variable.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
if (variableIsUsedInInnerClass(containingScope, variable)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isImmediatelyReturned(PsiVariable variable) {
|
||||
|
||||
final PsiCodeBlock containingScope =
|
||||
(PsiCodeBlock) PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
|
||||
if (containingScope == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiDeclarationStatement declarationStatement =
|
||||
(PsiDeclarationStatement) PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class);
|
||||
if (declarationStatement == null) {
|
||||
return false;
|
||||
}
|
||||
PsiStatement nextStatement = null;
|
||||
final PsiStatement[] statements = containingScope.getStatements();
|
||||
for (int i = 0; i < statements.length - 1; i++) {
|
||||
if (statements[i].equals(declarationStatement)) {
|
||||
nextStatement = statements[i + 1];
|
||||
}
|
||||
}
|
||||
if (nextStatement == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(nextStatement instanceof PsiReturnStatement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiReturnStatement returnStatement = (PsiReturnStatement) nextStatement;
|
||||
final PsiExpression returnValue = returnStatement.getReturnValue();
|
||||
if (returnValue == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(returnValue instanceof PsiReferenceExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) returnValue).resolve();
|
||||
if (referent == null || !referent.equals(variable)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isImmediatelyAssigned(PsiVariable variable) {
|
||||
|
||||
final PsiCodeBlock containingScope =
|
||||
(PsiCodeBlock) PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
|
||||
if (containingScope == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiDeclarationStatement declarationStatement =
|
||||
(PsiDeclarationStatement) PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class);
|
||||
if (declarationStatement == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiStatement nextStatement = null;
|
||||
int followingStatementNumber = 0;
|
||||
final PsiStatement[] statements = containingScope.getStatements();
|
||||
for (int i = 0; i < statements.length - 1; i++) {
|
||||
if (statements[i].equals(declarationStatement)) {
|
||||
nextStatement = statements[i + 1];
|
||||
followingStatementNumber = i + 2;
|
||||
}
|
||||
}
|
||||
if (nextStatement == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(nextStatement instanceof PsiExpressionStatement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpressionStatement expressionStatement = (PsiExpressionStatement) nextStatement;
|
||||
final PsiExpression expression = expressionStatement.getExpression();
|
||||
if (expression == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(expression instanceof PsiAssignmentExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiExpression rhs = ((PsiAssignmentExpression) expression).getRExpression();
|
||||
if (rhs == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(rhs instanceof PsiReferenceExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) rhs).resolve();
|
||||
if (referent == null || !referent.equals(variable)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = followingStatementNumber; i < statements.length; i++) {
|
||||
if (variableIsUsedInStatement(statements[i], variable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static boolean isImmediatelyAssignedAsDeclaration(PsiVariable variable) {
|
||||
|
||||
final PsiCodeBlock containingScope =
|
||||
(PsiCodeBlock) PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
|
||||
if (containingScope == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiDeclarationStatement declarationStatement =
|
||||
(PsiDeclarationStatement) PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class);
|
||||
if (declarationStatement == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiStatement nextStatement = null;
|
||||
int followingStatementNumber = 0;
|
||||
final PsiStatement[] statements = containingScope.getStatements();
|
||||
for (int i = 0; i < statements.length - 1; i++) {
|
||||
if (statements[i].equals(declarationStatement)) {
|
||||
nextStatement = statements[i + 1];
|
||||
followingStatementNumber = i + 2;
|
||||
}
|
||||
}
|
||||
if (nextStatement == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(nextStatement instanceof PsiDeclarationStatement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiDeclarationStatement declaration = (PsiDeclarationStatement) nextStatement;
|
||||
final PsiElement[] declarations = declaration.getDeclaredElements();
|
||||
if (declarations == null) {
|
||||
return false;
|
||||
}
|
||||
if (declarations.length != 1) {
|
||||
return false;
|
||||
}
|
||||
if (!(declarations[0] instanceof PsiVariable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiExpression rhs = ((PsiVariable) declarations[0]).getInitializer();
|
||||
if (rhs == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(rhs instanceof PsiReferenceExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement referent = ((PsiReferenceExpression) rhs).resolve();
|
||||
if (referent == null || !referent.equals(variable)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = followingStatementNumber; i < statements.length; i++) {
|
||||
if (variableIsUsedInStatement(statements[i], variable)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean variableIsUsedInInnerClass(PsiCodeBlock block,
|
||||
PsiVariable variable) {
|
||||
|
||||
final VariableUsedInInnerClassVisitor visitor
|
||||
= new VariableUsedInInnerClassVisitor(variable);
|
||||
block.accept(visitor);
|
||||
return visitor.isUsedInInnerClass();
|
||||
}
|
||||
|
||||
private static boolean variableIsUsedInStatement(PsiStatement statement,
|
||||
PsiVariable variable) {
|
||||
|
||||
final VariableUsedVisitor visitor
|
||||
= new VariableUsedVisitor(variable);
|
||||
statement.accept(visitor);
|
||||
return visitor.isUsed();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of <b><font color="#000080">catch</font></b> clauses
|
||||
which catch inappropriate exceptions. Some exceptions, for instance
|
||||
<b><font color="#000080">java.lang.NullPointerException</font></b> and
|
||||
<b><font color="#000080">java.lang.IllegalMonitorStateException</font></b> represent programming errors
|
||||
and so should almost certainly not be caught in production code.
|
||||
<p>
|
||||
Use the list below to specify which exceptions should be flagged by this inspection.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of <b><font color="#000080">throws</font></b> clauses on
|
||||
methods which throw inappropriate exceptions. One use of this inspection would be to warn of
|
||||
<b><font color="#000080">throws</font></b> clauses which throw overly generic exceptions
|
||||
(e.g. <b><font color="#000080">java.lang.Exception</font></b>) or
|
||||
<p>
|
||||
Use the list below to specify which exceptions should be flagged by this inspection.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of <b><font color="#000080">throw</font></b> statements
|
||||
which throw inappropriate exceptions. One use of this inspection would be to warn of
|
||||
<b><font color="#000080">throw</font></b> statements which throw overly generic exceptions
|
||||
(e.g. <b><font color="#000080">java.lang.Exception</font></b> or
|
||||
<b><font color="#000080">java.io.IOException</font></b>).
|
||||
<p>
|
||||
Use the list below to specify which exceptions should be flagged by this inspection.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any to methods declared <b><font color="#000080">native</font></b> while in
|
||||
a synchronized block or method. While not necessarily representing a problem, such calls cause
|
||||
an expensive context switch, and are best kept out of synchronized contexts, if possible.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any I/O resource which is not opened in a <b><font color="#000080">try</font></b>
|
||||
block and closed in the corresponding <b><font color="#000080">finally</font></b> block. Such resources may
|
||||
be inadvertantly leaked if an exception is thrown before the resouce is closed. I/O resources reported
|
||||
by this inspection include any instances of <b><font color="#000080">java.io.InputStream</font></b>,
|
||||
<b><font color="#000080">java.io.OutputStream</font></b>,
|
||||
<b><font color="#000080">java.io.Reader</font></b>,
|
||||
<b><font color="#000080">java.io.Writer</font></b> and
|
||||
<b><font color="#000080">java.io.RandomAccessFile</font></b> . I/O resources which are wrapped by other I/O resources
|
||||
are not reported, as the wrapped resource will be closed by the wrapping resource.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any chains of if-else statements all of whose conditions are <b><font color="#000080">instanceof</font></b> expressions
|
||||
(or combinations of such expressions). Such constructions usually indicate a failure of object-oriented design, which
|
||||
dictates that such type-based dispatch should be done via polymorphic method calls rather than explicit chains
|
||||
of type tests.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any JDBC resource which is not opened in a <b><font color="#000080">try</font></b>
|
||||
block and closed in the corresponding <b><font color="#000080">finally</font></b> block. Such resources may
|
||||
be inadvertantly leaked if an exception is thrown before the resouce is closed. JDBC resources reported
|
||||
by this inspection include any instances of <b><font color="#000080">java.sql.Connection</font></b>,
|
||||
<b><font color="#000080">java.sql.Statement</font></b>,
|
||||
<b><font color="#000080">java.sql.PreparedStatement</font></b>,
|
||||
<b><font color="#000080">java.sql.CallableStatement</font></b>,
|
||||
and <b><font color="#000080">java.sql.ResultSet</font></b>.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">This inspection reports any calls to JUnit assertEquals() which have
|
||||
a non-literal as the expected result argument and a literal as the actual result argument. Such calls
|
||||
will behave fine for assertions which pass, but may give confusing error reports if their expected and actual
|
||||
arguments differ.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of parameters which have different names from corresponding
|
||||
parameters in methods they override. While legal in Java, such inconsistent names may be confusing,
|
||||
and lessen the documentation benefits of good naming practices.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of <b><font color="#000080">Serializable</font></b> classes whose <b><font color="#000080">serialPersistentFields</font></b> field.
|
||||
is not declared <b><font color="#000080">private static final ObjectStreamField</font ></b>.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instantiations of <b><font color="#000080">java.util.SimpleDateFormat</font></b>
|
||||
which do not specify a <b><font color="#000080">java.util.Locale</font></b>.
|
||||
Such calls are usually incorrect in an internationalized environment.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">This inspection reports any JUnit <b><font color="#000080">assertTrue</font></b> calls
|
||||
which can be replaced by equivalent <b><font color="#000080">assertEquals</font></b> calls. <b><font color="#000080">assertEquals</font></b>
|
||||
calls will normally give better error messages in case of test failure than <b><font color="#000080">assertTrue</font></b> can.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of static method calls where the call is qualified
|
||||
by a subclass of the declaring class, rather than the declaring class itself
|
||||
(e.g. MyThreadSubclass.sleep()). Java allows such qualification, but such calls
|
||||
may be confusing, and may indicate a subtle confusion of inheritance and overriding.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of fields with type
|
||||
<b><font color="#000080">java.lang.StringBuffer</font></b> or <b><font color="#000080">java.lang.StringBuilder</font></b>.
|
||||
StringBuffer fields can grow without limit, and are often the cause of
|
||||
memory leaks.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of JUnit test cases in product source trees.
|
||||
This most likely indicates programmer error, and can result in test code being shipped
|
||||
into production.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of non-abstract JUnit test cases which do not
|
||||
expose a public no-arg constructor or a public constructor which takes a single string
|
||||
as an argument. Such test cases will be unrunnable by most JUnit test runners, including
|
||||
IDEA's.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of unnecessary public no-arg constructors.
|
||||
If such a constructor is the only constructor for a class and performs no initialization,
|
||||
it can be safely removed.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any instances of unnecessary local variables, which add
|
||||
nothing to the comprehensibility of a method. Variables caught include local variables
|
||||
which are immediately returned, local variables that are immediately assigned to another
|
||||
variable and then not used, and local variables which always have the same value as another
|
||||
local variable or parameter.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<html>
|
||||
<body><table> <tr> <td valign = "top" height="150">
|
||||
<font face="verdana" size="-1">
|
||||
This inspection reports any uses of another object's private or protected fields. Java
|
||||
allows the use of such fields for objects of the same class as the current objects, but
|
||||
some coding styles discourage this use. Additionally, such direct access to private fields
|
||||
may fail in component-oriented architectures such (e.g. Spring, Hibernate) which expect all access
|
||||
to other objects to be through method calls so as to allow the framework to mediate all access
|
||||
using proxies.
|
||||
</font></td> </tr> <tr> <td height="20"> <font face="verdana" size="-2">Powered by InspectionGadgets </font> </td> </tr> </table> </body>
|
||||
</html>
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.siyeh.igtest.abstraction;
|
||||
|
||||
class TestFeatureEnvySuper {
|
||||
void foo1() {
|
||||
}
|
||||
|
||||
void foo2() {
|
||||
}
|
||||
|
||||
void foo3() {
|
||||
}
|
||||
}
|
||||
|
||||
class TestFeatureEnvySuper2 {
|
||||
void test() {
|
||||
TestFeatureEnvySuper test = new TestFeatureEnvySuper();
|
||||
test.foo1();
|
||||
test.foo2();
|
||||
test.foo3();
|
||||
}
|
||||
}
|
||||
|
||||
public class FeatureEnvy extends TestFeatureEnvySuper {
|
||||
class Inner {
|
||||
void test() {
|
||||
foo1();
|
||||
foo2();
|
||||
foo3();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.siyeh.igtest.bugs;
|
||||
|
||||
public class StaticCallOnSubclass {
|
||||
|
||||
public void foo() throws InterruptedException {
|
||||
Thread.sleep(1000L);
|
||||
InnerThread.sleep(1000L);
|
||||
}
|
||||
|
||||
class InnerThread extends Thread
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.siyeh.igtest.encapsulation;
|
||||
|
||||
public class UseOfAnotherObjectsPrivateFieldInspection {
|
||||
public int foo;
|
||||
protected int bar;
|
||||
private int baz;
|
||||
|
||||
public void fooBar(UseOfAnotherObjectsPrivateFieldInspection copy)
|
||||
{
|
||||
foo = copy.foo;
|
||||
bar = copy.bar;
|
||||
baz = copy.baz;
|
||||
foo = this.baz;
|
||||
foo = baz;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.siyeh.igtest.junit;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class UnconstructableTestCase1 extends TestCase
|
||||
{
|
||||
private UnconstructableTestCase1()
|
||||
{
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.siyeh.igtest.junit;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class UnconstructableTestCase2 extends TestCase
|
||||
{
|
||||
public UnconstructableTestCase2(Object foo)
|
||||
{
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.siyeh.igtest.junit;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class UnconstructableTestCase3 extends TestCase
|
||||
{
|
||||
public UnconstructableTestCase3()
|
||||
{
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.siyeh.igtest.junit;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class UnconstructableTestCase4 extends TestCase
|
||||
{
|
||||
public UnconstructableTestCase4(String foo)
|
||||
{
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.siyeh.igtest.naming.package2;
|
||||
|
||||
public class Test {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.siyeh.igtest.naming.package2;
|
||||
|
||||
public class Test2 {
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.siyeh.igtest.portability;
|
||||
|
||||
public class AutoUnboxingInspection {
|
||||
public void foo() {
|
||||
Integer bar = 3;
|
||||
int baz = new Integer(3);
|
||||
if (new Integer(3) == 3) {
|
||||
return;
|
||||
}
|
||||
if (new Integer(3) + 3 == 3) {
|
||||
return;
|
||||
}
|
||||
Integer x = 3;
|
||||
}
|
||||
}
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
package com.siyeh.igtest.resources;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
public class JDBCResourceInspection {
|
||||
private Driver driver;
|
||||
|
||||
public void foo() throws SQLException {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo2() throws SQLException {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void foo3() throws SQLException {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
connection.createStatement();
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo4() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.createStatement();
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo5() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.createStatement();
|
||||
} finally {
|
||||
statement.close();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo6() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.prepareStatement("foo");
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo7() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.prepareStatement("foo");
|
||||
} finally {
|
||||
statement.close();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo8() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.prepareCall("foo");
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo9() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.prepareCall("foo");
|
||||
} finally {
|
||||
statement.close();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo10() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
ResultSet resultSet = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.prepareCall("foo");
|
||||
resultSet = statement.executeQuery("foo");
|
||||
} finally {
|
||||
statement.close();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void foo11() throws SQLException {
|
||||
Connection connection = null;
|
||||
Statement statement = null;
|
||||
ResultSet resultSet = null;
|
||||
try {
|
||||
connection = driver.connect("foo", null);
|
||||
statement = connection.prepareCall("foo");
|
||||
resultSet = statement.executeQuery("foo");
|
||||
} finally {
|
||||
resultSet.close();
|
||||
statement.close();
|
||||
connection.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package com.siyeh.igtest.verbose;
|
||||
|
||||
public class UnnecessaryBlockStatementInspection {
|
||||
public static void main(String[] args) {
|
||||
{
|
||||
System.out.println("3");
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.siyeh.igtest.verbose;
|
||||
|
||||
public class UnnecessaryLocalVariableInspection {
|
||||
|
||||
public int foo() {
|
||||
int a = 2;
|
||||
int b = a;
|
||||
return b;
|
||||
}
|
||||
|
||||
public int bar() {
|
||||
int b = 3;
|
||||
return b;
|
||||
}
|
||||
|
||||
public int baz() {
|
||||
int a;
|
||||
int b = 3;
|
||||
a = b;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user