summaryrefslogtreecommitdiff
path: root/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh')
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties26
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ResultSetIndexZeroInspection.java8
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringEqualityInspection.java10
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassWithOnlyPrivateConstructorsInspectionBase.java3
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopConditionNotUpdatedInsideLoopInspection.java6
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/DoubleBraceInitializationInspection.java216
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java246
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspectionBase.java132
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/AnonymousInnerClassMayBeStaticInspectionBase.java74
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspectionBase.java (renamed from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspection.java)10
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspectionBase.java110
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/InnerClassMayBeStaticInspection.java (renamed from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassMayBeStaticInspection.java)4
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/InnerClassReferenceVisitor.java126
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java149
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java3
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java9
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java102
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/NestedMethodCallInspectionBase.java19
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java116
19 files changed, 787 insertions, 582 deletions
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index 1df72421fd4d..949ae7667e76 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -445,8 +445,8 @@ use.processbuilder.class.problem.descriptor=Use of <code>#ref</code> is non-port
use.sun.classes.display.name=Use of sun.* classes
use.sun.classes.problem.descriptor=Use of Sun-supplied class <code>#ref</code> is non-portable #loc
abstract.class.with.only.one.direct.inheritor.display.name=Abstract class which has only one direct inheritor
-anonymous.inner.may.be.named.static.inner.class.display.name=Anonymous inner class may be a named static inner class
-anonymous.inner.may.be.named.static.inner.class.problem.descriptor=Anonymous inner class <code>#ref</code> may be a named static inner class #loc
+anonymous.inner.may.be.named.static.inner.class.display.name=Anonymous class may be a named 'static' inner class
+anonymous.inner.may.be.named.static.inner.class.problem.descriptor=Anonymous class <code>#ref</code> may be a named 'static' inner class #loc
array.length.in.loop.condition.display.name=Array.length in loop condition
array.length.in.loop.condition.problem.descriptor=Check of array <code>#ref</code> in loop condition #loc
large.array.allocation.no.outofmemoryerror.display.name=Large array allocation with no OutOfMemoryError check
@@ -992,7 +992,8 @@ constant.on.lhs.of.comparison.problem.descriptor=<code>#ref</code>: constant on
constant.on.rhs.of.comparison.problem.descriptor=<code>#ref</code>: constant on right side of comparison #loc
control.flow.statement.without.braces.problem.descriptor=<code>#ref</code> without braces #loc
missorted.modifiers.problem.descriptor=Missorted modifiers <code>#ref</code> #loc
-c.style.array.declaration.problem.descriptor=C-style array declaration <code>#ref</code> #loc
+cstyle.array.variable.declaration.problem.descriptor=C-style array declaration of {0, choice, 1#field|2#parameter|3#local variable} <code>#ref</code> #loc
+cstyle.array.method.declaration.problem.descriptor=C-style array declaration of the return type of method <code>#ref()</code>#loc
multiple.declaration.problem.descriptor=Multiple variables in one declaration #loc
multiple.typed.declaration.problem.descriptor=Variables of different types in one declaration #loc
serializable.inner.class.has.serial.version.uid.field.problem.descriptor=Inner class <code>#ref</code> does not define a 'serialVersionUID' field #loc
@@ -1290,7 +1291,7 @@ call.to.simple.getter.in.class.inline.quickfix=Inline call to getter
call.to.simple.setter.in.class.ignore.option=Ignore setter calls on other objects
call.to.private.setter.in.class.option=Only report when setter is private
call.to.simple.setter.in.class.inline.quickfix=Inline call to setter
-make.static.quickfix=Make static
+make.static.quickfix=Make 'static'
length.one.strings.in.concatenation.replace.quickfix=Replace with character
multiply.or.divide.by.power.of.two.replace.quickfix=Replace with shift
boolean.expression.can.be.simplified.problem.descriptor=<code>#ref</code> can be simplified to ''{0}'' #loc
@@ -1366,6 +1367,8 @@ implicit.call.to.super.make.explicit.quickfix=Make call to 'super()' explicit
missorted.modifiers.require.option=Require annotations to be sorted before keywords
missorted.modifiers.sort.quickfix=Sort modifiers
nested.method.call.ignore.option=Ignore nested method calls in field initializers
+ignore.calls.to.static.methods=Ignore calls to static methods
+ignore.calls.to.property.getters=Ignore calls to property getters
redundant.field.initialization.remove.quickfix=Remove initializer
redundant.implements.remove.quickfix=Remove redundant interface declaration
unnecessary.constructor.remove.quickfix=Remove redundant constructor
@@ -1691,8 +1694,8 @@ char.used.in.arithmetic.context.cast.quickfix=Insert cast to {0}
unnecessary.constant.array.creation.expression.display.name=Constant array creation expression can be replaced with array initializer
unnecessary.constant.array.creation.expression.problem.descriptor=<code>#ref</code> can be replaced with array initializer expression #loc
unnecessary.constant.array.creation.expression.quickfix=Replace with array initializer expression
-ambiguous.method.call.display.name=Inherited method called, while local method might have been expected
-ambiguous.method.call.problem.descriptor=Method <code>#ref()</code> from superclass ''{0}'' called, when method from class ''{1}'' might have been expected #loc
+ambiguous.method.call.display.name=Call to inherited method looks like call to local method
+ambiguous.method.call.problem.descriptor=Call to method <code>#ref()</code> from superclass ''{0}'' looks like call to method from class ''{1}'' #loc
ambiguous.method.call.quickfix=Add 'super' qualifier to method call
change.modifier.quickfix=Make ''{0}''
the.whole.project=the whole project
@@ -1969,10 +1972,10 @@ throws.runtime.exception.problem.descriptor=Unchecked exception <code>#ref</code
throws.runtime.exception.quickfix=Remove ''{0}'' from ''throws'' clause
throws.runtime.exception.move.quickfix=Move ''{0}'' to Javadoc ''@throws'' tag
empty.class.ignore.parameterization.option=Ignore class if it is a parameterization of a super type
-ambiguous.field.access.display.name=Inherited field accessed while local variable, parameter or field access from surrounding class might be expected
-ambiguous.field.access.hides.local.variable.problem.descriptor=Field <code>#ref</code> from superclass ''{0}'' accessed, while local variable access might be expected #loc
-ambiguous.field.access.hides.parameter.problem.descriptor=Field <code>#ref</code> from superclass ''{0}'' accessed, while parameter access might be expected #loc
-ambiguous.field.access.hides.field.problem.descriptor=Field <code>#ref</code> from superclass ''{0}'' accessed, while field access from surrounding class might be expected #loc
+ambiguous.field.access.display.name=Access of inherited field looks like access of element in surrounding code
+ambiguous.field.access.hides.local.variable.problem.descriptor=Access of field <code>#ref</code> from superclass ''{0}'' looks like access of local variable #loc
+ambiguous.field.access.hides.parameter.problem.descriptor=Access of field <code>#ref</code> from superclass ''{0}'' looks like access of parameter #loc
+ambiguous.field.access.hides.field.problem.descriptor=Access of field <code>#ref</code> from superclass ''{0}'' looks access of field from surrounding class #loc
ambiguous.field.access.quickfix=Add 'super' qualifier to field access
string.builder.replaceable.by.string.quickfix=Replace 'StringBuilder' with 'String'
string.buffer.replaceable.by.string.quickfix=Replace 'StringBuffer' with 'String'
@@ -2111,3 +2114,6 @@ junit3.method.naming.convention.display.name=JUnit 3 test method naming conventi
junit3.method.naming.convention.problem.descriptor.short=JUnit 3 test method name <code>#ref</code> is too short ({0} < {1}) #loc
junit3.method.naming.convention.problem.descriptor.long=JUnit 3 test method name <code>#ref</code> is too long ({0} > {1}) #loc
junit3.method.naming.convention.problem.descriptor.regex.mismatch=JUnit 3 test method name <code>#ref</code> doesn''t match regex ''{0}'' #loc
+introduce.holder.class.quickfix=Introduce holder class
+double.brace.initialization.display.name=Double brace initialization
+double.brace.initialization.quickfix=Replace with regular initialization
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ResultSetIndexZeroInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ResultSetIndexZeroInspection.java
index 626d4508e731..a72f297e483c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ResultSetIndexZeroInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ResultSetIndexZeroInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -87,11 +87,11 @@ public class ResultSetIndexZeroInspection extends BaseInspection {
final PsiExpression qualifier = methodExpression.getQualifierExpression();
if (resultSet) {
if (TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.ResultSet")) {
- registerError(argument, Boolean.valueOf(resultSet));
+ registerError(argument, Boolean.TRUE);
}
- } else {
+ } else if (arguments.length > 1) {
if (TypeUtils.expressionHasTypeOrSubtype(qualifier, "java.sql.PreparedStatement")) {
- registerError(argument, Boolean.valueOf(resultSet));
+ registerError(argument, Boolean.FALSE);
}
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringEqualityInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringEqualityInspection.java
index 0ac07245fd8f..f94f495993d7 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringEqualityInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringEqualityInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package com.siyeh.ig.bugs;
import com.intellij.psi.PsiBinaryExpression;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiJavaToken;
-import com.intellij.psi.PsiKeyword;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -73,12 +72,7 @@ public class StringEqualityInspection extends BaseInspection {
if (rhs == null || !ExpressionUtils.hasStringType(rhs)) {
return;
}
- final String lhsText = lhs.getText();
- if (PsiKeyword.NULL.equals(lhsText)) {
- return;
- }
- final String rhsText = rhs.getText();
- if (PsiKeyword.NULL.equals(rhsText)) {
+ if (ExpressionUtils.isNullLiteral(lhs) || ExpressionUtils.isNullLiteral(rhs)) {
return;
}
final PsiJavaToken sign = expression.getOperationSign();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassWithOnlyPrivateConstructorsInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassWithOnlyPrivateConstructorsInspectionBase.java
index 6d091699ce82..b6583b4ede75 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassWithOnlyPrivateConstructorsInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/ClassWithOnlyPrivateConstructorsInspectionBase.java
@@ -54,6 +54,9 @@ public class ClassWithOnlyPrivateConstructorsInspectionBase extends BaseInspecti
@Override
public void visitClass(PsiClass aClass) {
super.visitClass(aClass);
+ if (aClass.isEnum()) {
+ return;
+ }
final PsiMethod[] constructors = aClass.getConstructors();
if (constructors.length == 0) {
return;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopConditionNotUpdatedInsideLoopInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopConditionNotUpdatedInsideLoopInspection.java
index 46969fd5bcfc..57c635b7d461 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopConditionNotUpdatedInsideLoopInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/LoopConditionNotUpdatedInsideLoopInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2013 Bas Leijdekkers
+ * Copyright 2006-2014 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.BoolUtils;
+import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.IteratorUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NotNull;
@@ -118,8 +119,7 @@ public class LoopConditionNotUpdatedInsideLoopInspection
if (condition == null) {
return false;
}
- if (PsiUtil.isConstantExpression(condition) ||
- PsiKeyword.NULL.equals(condition.getText())) {
+ if (PsiUtil.isConstantExpression(condition) || ExpressionUtils.isNullLiteral(condition)) {
return true;
}
if (condition instanceof PsiInstanceOfExpression) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/DoubleBraceInitializationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/DoubleBraceInitializationInspection.java
new file mode 100644
index 000000000000..bdf58e720d8d
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/DoubleBraceInitializationInspection.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.initialization;
+
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.InspectionGadgetsFix;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class DoubleBraceInitializationInspection extends BaseInspection {
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message("double.brace.initialization.display.name");
+ }
+
+ @NotNull
+ @Override
+ protected String buildErrorString(Object... infos) {
+ return InspectionGadgetsBundle.message("double.brace.initialization.display.name");
+ }
+
+ @Nullable
+ @Override
+ protected InspectionGadgetsFix buildFix(Object... infos) {
+ final PsiClass aClass = (PsiClass)infos[0];
+ final PsiElement parent = PsiTreeUtil.skipParentsOfType(aClass, PsiNewExpression.class, ParenthesesUtils.class);
+ if (!(parent instanceof PsiVariable) && !(parent instanceof PsiAssignmentExpression)) {
+ return null;
+ }
+ return new DoubleBraceInitializationFix();
+ }
+
+ private static class DoubleBraceInitializationFix extends InspectionGadgetsFix {
+
+ @NotNull
+ @Override
+ public String getName() {
+ return InspectionGadgetsBundle.message("double.brace.initialization.quickfix");
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
+ @Override
+ protected void doFix(Project project, ProblemDescriptor descriptor) {
+ final PsiElement element = descriptor.getPsiElement().getParent();
+ if (!(element instanceof PsiAnonymousClass)) {
+ return;
+ }
+ final PsiAnonymousClass aClass = (PsiAnonymousClass)element;
+ final PsiElement parent = aClass.getParent();
+ if (!(parent instanceof PsiNewExpression)) {
+ return;
+ }
+ final PsiNewExpression newExpression = (PsiNewExpression)parent;
+ final PsiElement ancestor = PsiTreeUtil.skipParentsOfType(newExpression, ParenthesesUtils.class);
+ final String qualifierText;
+ if (ancestor instanceof PsiVariable) {
+ qualifierText = ((PsiVariable)ancestor).getName();
+ }
+ else if (ancestor instanceof PsiAssignmentExpression) {
+ final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)ancestor;
+ final PsiExpression lhs = ParenthesesUtils.stripParentheses(assignmentExpression.getLExpression());
+ if (!(lhs instanceof PsiReferenceExpression)) {
+ return;
+ }
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)lhs;
+ final PsiElement target = referenceExpression.resolve();
+ if (!(target instanceof PsiVariable)) {
+ return;
+ }
+ qualifierText = referenceExpression.getText();
+ }
+ else {
+ return;
+ }
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+ final PsiJavaCodeReferenceElement baseClassReference = aClass.getBaseClassReference();
+ final PsiElement baseClassTarget = baseClassReference.resolve();
+ if (!(baseClassTarget instanceof PsiClass)) {
+ return;
+ }
+ final PsiExpressionList argumentList = aClass.getArgumentList();
+ if (argumentList == null) {
+ return;
+ }
+ qualifyReferences(aClass, (PsiClass) baseClassTarget, qualifierText);
+ final PsiClassInitializer initializer = aClass.getInitializers()[0];
+ final PsiCodeBlock body = initializer.getBody();
+ PsiElement child = body.getLastBodyElement();
+ final PsiElement stop = body.getFirstBodyElement();
+ final PsiElement anchor = PsiTreeUtil.getParentOfType(aClass, PsiMember.class, PsiStatement.class);
+ if (anchor == null) {
+ return;
+ }
+ if (anchor instanceof PsiMember) {
+ final PsiMember member = (PsiMember)anchor;
+ final PsiClassInitializer newInitializer = factory.createClassInitializer();
+ if (member.hasModifierProperty(PsiModifier.STATIC)) {
+ final PsiModifierList modifierList = newInitializer.getModifierList();
+ if (modifierList != null) {
+ modifierList.setModifierProperty(PsiModifier.STATIC, true);
+ }
+ }
+ final PsiCodeBlock initializerBody = newInitializer.getBody();
+ while (child != null && !child.equals(stop)) {
+ initializerBody.add(child);
+ child = child.getPrevSibling();
+ }
+ member.getParent().addAfter(newInitializer, member);
+ }
+ else {
+ final PsiElement container = anchor.getParent();
+ while (child != null && !child.equals(stop)) {
+ container.addAfter(child, anchor);
+ child = child.getPrevSibling();
+ }
+ }
+ final PsiExpression newNewExpression =
+ factory.createExpressionFromText("new " + baseClassReference.getText() + argumentList.getText(), aClass);
+ newExpression.replace(newNewExpression);
+ }
+
+ private static void qualifyReferences(PsiElement element, final PsiClass target, final String qualifierText) {
+ final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject());
+ element.accept(new JavaRecursiveElementVisitor() {
+ @Override
+ public void visitReferenceExpression(PsiReferenceExpression expression) {
+ super.visitReferenceExpression(expression);
+ if (expression.getQualifierExpression() != null) {
+ return;
+ }
+ final PsiElement expressionTarget = expression.resolve();
+ if (!(expressionTarget instanceof PsiMember)) {
+ return;
+ }
+ final PsiMember member = (PsiMember)expressionTarget;
+ final PsiClass containingClass = member.getContainingClass();
+ if (!target.equals(containingClass)) {
+ return;
+ }
+ final PsiExpression newExpression = factory.createExpressionFromText(qualifierText + '.' + expression.getText(), expression);
+ expression.replace(newExpression);
+ }
+ });
+ }
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new DoubleBraceInitializationVisitor();
+ }
+
+ private static class DoubleBraceInitializationVisitor extends BaseInspectionVisitor {
+
+ @Override
+ public void visitAnonymousClass(PsiAnonymousClass aClass) {
+ super.visitAnonymousClass(aClass);
+ final PsiClassInitializer[] initializers = aClass.getInitializers();
+ if (initializers.length != 1) {
+ return;
+ }
+ final PsiClassInitializer initializer = initializers[0];
+ if (initializer.hasModifierProperty(PsiModifier.STATIC)) {
+ // don't warn on broken code
+ return;
+ }
+ final PsiField[] fields = aClass.getFields();
+ if (fields.length != 0) {
+ return;
+ }
+ final PsiMethod[] methods = aClass.getMethods();
+ if (methods.length != 0) {
+ return;
+ }
+ final PsiClass[] innerClasses = aClass.getInnerClasses();
+ if (innerClasses.length != 0) {
+ return;
+ }
+ final PsiJavaCodeReferenceElement reference = aClass.getBaseClassReference();
+ if (reference.resolve() == null) {
+ return;
+ }
+ registerClassError(aClass, aClass);
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java
deleted file mode 100644
index 2e0bebac17b9..000000000000
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspection.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.siyeh.ig.initialization;
-
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.Processor;
-import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.InspectionGadgetsFix;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collection;
-
-public class NonThreadSafeLazyInitializationInspection
- extends BaseInspection {
-
- @Override
- @NotNull
- public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "non.thread.safe.lazy.initialization.display.name");
- }
-
- @Override
- @NotNull
- public String buildErrorString(Object... infos) {
- return InspectionGadgetsBundle.message(
- "non.thread.safe.lazy.initialization.problem.descriptor");
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new UnsafeSafeLazyInitializationVisitor();
- }
-
- private static class UnsafeSafeLazyInitializationVisitor
- extends BaseInspectionVisitor {
-
- @Override
- public void visitAssignmentExpression(
- @NotNull PsiAssignmentExpression expression) {
- super.visitAssignmentExpression(expression);
- final PsiExpression lhs = expression.getLExpression();
- if (!(lhs instanceof PsiReferenceExpression)) {
- return;
- }
- final PsiReference reference = (PsiReference)lhs;
- final PsiElement referent = reference.resolve();
- if (!(referent instanceof PsiField)) {
- return;
- }
- final PsiField field = (PsiField)referent;
- if (!field.hasModifierProperty(PsiModifier.STATIC)) {
- return;
- }
- if (isInStaticInitializer(expression)) {
- return;
- }
- if (isInSynchronizedContext(expression)) {
- return;
- }
- if (!isLazy(expression, (PsiReferenceExpression)lhs)) {
- return;
- }
- boolean assignedOnce = isAssignedOnce(referent);
- boolean safeToDelete = isSafeToDeleteIfStatement(expression);
- registerError(lhs, assignedOnce && safeToDelete);
- }
-
- private static boolean isAssignedOnce(PsiElement referent) {
- final int[] writeCount = new int[1];
- return ReferencesSearch.search(referent).forEach(new Processor<PsiReference>() {
- @Override
- public boolean process(PsiReference reference) {
- PsiElement element = reference.getElement();
- if (!(element instanceof PsiExpression)) {
- return true;
- }
- if (!PsiUtil.isAccessedForWriting((PsiExpression)element)) {
- return true;
- }
- return ++writeCount[0] != 2;
- }
- });
- }
-
- private static boolean isSafeToDeleteIfStatement(PsiElement expression) {
- PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(expression, PsiIfStatement.class);
- if (ifStatement.getElseBranch() != null) {
- return false;
- }
- PsiStatement thenBranch = ifStatement.getThenBranch();
- if (thenBranch == null) return false;
- if (!(thenBranch instanceof PsiBlockStatement)) {
- return true;
- }
- return ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements().length == 1;
- }
-
- private static boolean isLazy(PsiAssignmentExpression expression,
- PsiReferenceExpression lhs) {
- final PsiIfStatement ifStatement =
- PsiTreeUtil.getParentOfType(expression,
- PsiIfStatement.class);
- if (ifStatement == null) {
- return false;
- }
- final PsiExpression condition = ifStatement.getCondition();
- if (condition == null) {
- return false;
- }
- return isNullComparison(condition, lhs);
- }
-
- private static boolean isNullComparison(
- PsiExpression condition, PsiReferenceExpression reference) {
- if (!(condition instanceof PsiBinaryExpression)) {
- return false;
- }
- final PsiBinaryExpression comparison =
- (PsiBinaryExpression)condition;
- final IElementType tokenType = comparison.getOperationTokenType();
- if (!tokenType.equals(JavaTokenType.EQEQ)) {
- return false;
- }
- final PsiExpression lhs = comparison.getLOperand();
- final PsiExpression rhs = comparison.getROperand();
- if (rhs == null) {
- return false;
- }
- final String lhsText = lhs.getText();
- final String rhsText = rhs.getText();
- if (!PsiKeyword.NULL.equals(lhsText) &&
- !PsiKeyword.NULL.equals(rhsText)) {
- return false;
- }
- final String referenceText = reference.getText();
- return referenceText.equals(lhsText) ||
- referenceText.equals(rhsText);
- }
-
- private static boolean isInSynchronizedContext(PsiElement element) {
- final PsiSynchronizedStatement syncBlock =
- PsiTreeUtil.getParentOfType(element,
- PsiSynchronizedStatement.class);
- if (syncBlock != null) {
- return true;
- }
- final PsiMethod method =
- PsiTreeUtil.getParentOfType(element,
- PsiMethod.class);
- return method != null &&
- method.hasModifierProperty(PsiModifier.SYNCHRONIZED)
- && method.hasModifierProperty(PsiModifier.STATIC);
- }
-
- private static boolean isInStaticInitializer(PsiElement element) {
- final PsiClassInitializer initializer =
- PsiTreeUtil.getParentOfType(element,
- PsiClassInitializer.class);
- return initializer != null &&
- initializer.hasModifierProperty(PsiModifier.STATIC);
- }
- }
-
- @Override
- protected InspectionGadgetsFix buildFix(Object... infos) {
- boolean isApplicable = ((Boolean)infos[0]).booleanValue();
- return isApplicable ? new IntroduceHolderFix() : null;
- }
-
- private static class IntroduceHolderFix extends InspectionGadgetsFix {
- @Override
- protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
- PsiReferenceExpression expression = (PsiReferenceExpression)descriptor.getPsiElement();
- PsiElement resolved = expression.resolve();
- if (!(resolved instanceof PsiField)) return;
- PsiField field = (PsiField)resolved;
- String holderName = suggestHolderName(field);
- @NonNls String text = "private static class " + holderName
- + " {" +
- "private static final " + field.getType().getCanonicalText() + " " +
- field.getName() + " = " + ((PsiAssignmentExpression)expression.getParent()).getRExpression().getText() + ";"
- + "}";
- PsiElementFactory elementFactory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();
- PsiClass holder = elementFactory.createClassFromText(text, field).getInnerClasses()[0];
- PsiMethod method = PsiTreeUtil.getParentOfType(expression, PsiMethod.class);
- method.getParent().addBefore(holder, method);
-
- PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(expression, PsiIfStatement.class);
- ifStatement.delete();
-
- final PsiExpression holderReference = elementFactory.createExpressionFromText(holderName + "." + field.getName(), field);
- Collection<PsiReference> references = ReferencesSearch.search(field).findAll();
- for (PsiReference reference : references) {
- PsiElement element = reference.getElement();
- element.replace(holderReference);
- }
- field.delete();
- }
-
- @NonNls
- private static String suggestHolderName(PsiField field) {
- String string = field.getType().getDeepComponentType().getPresentableText();
- final int index = string.indexOf('<');
- if (index != -1) {
- string = string.substring(0, index);
- }
- return string + "Holder";
- }
-
- @Override
- @NotNull
- public String getName() {
- return "Introduce holder class";
- }
-
- @NotNull
- @Override
- public String getFamilyName() {
- return getName();
- }
- }
-} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspectionBase.java
new file mode 100644
index 000000000000..f29c461bcf64
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/initialization/NonThreadSafeLazyInitializationInspectionBase.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.initialization;
+
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.ExpressionUtils;
+import com.siyeh.ig.psiutils.VariableAccessUtils;
+import org.jetbrains.annotations.NotNull;
+
+public class NonThreadSafeLazyInitializationInspectionBase extends BaseInspection {
+
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message(
+ "non.thread.safe.lazy.initialization.display.name");
+ }
+
+ @Override
+ @NotNull
+ public String buildErrorString(Object... infos) {
+ return InspectionGadgetsBundle.message(
+ "non.thread.safe.lazy.initialization.problem.descriptor");
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new UnsafeSafeLazyInitializationVisitor();
+ }
+
+ private static class UnsafeSafeLazyInitializationVisitor
+ extends BaseInspectionVisitor {
+
+ @Override
+ public void visitAssignmentExpression(
+ @NotNull PsiAssignmentExpression expression) {
+ super.visitAssignmentExpression(expression);
+ final PsiExpression lhs = expression.getLExpression();
+ if (!(lhs instanceof PsiReferenceExpression)) {
+ return;
+ }
+ final PsiReferenceExpression reference = (PsiReferenceExpression)lhs;
+ final PsiElement referent = reference.resolve();
+ if (!(referent instanceof PsiField)) {
+ return;
+ }
+ final PsiField field = (PsiField)referent;
+ if (!field.hasModifierProperty(PsiModifier.STATIC)) {
+ return;
+ }
+ if (isInStaticInitializer(expression)) {
+ return;
+ }
+ if (isInSynchronizedContext(expression)) {
+ return;
+ }
+ final PsiStatement statement = PsiTreeUtil.getParentOfType(expression, PsiStatement.class);
+ final PsiElement parent =
+ PsiTreeUtil.skipParentsOfType(statement, PsiCodeBlock.class, PsiBlockStatement.class);
+ if (!(parent instanceof PsiIfStatement)) {
+ return;
+ }
+ final PsiIfStatement ifStatement = (PsiIfStatement)parent;
+ final PsiExpression condition = ifStatement.getCondition();
+ if (condition == null|| !isNullComparison(condition, field)) {
+ return;
+ }
+ registerError(lhs, ifStatement, field);
+ }
+
+ private static boolean isNullComparison(PsiExpression condition, PsiVariable variable) {
+ if (!(condition instanceof PsiBinaryExpression)) {
+ return false;
+ }
+ final PsiBinaryExpression comparison = (PsiBinaryExpression)condition;
+ final IElementType tokenType = comparison.getOperationTokenType();
+ if (!tokenType.equals(JavaTokenType.EQEQ)) {
+ return false;
+ }
+ final PsiExpression lhs = comparison.getLOperand();
+ final PsiExpression rhs = comparison.getROperand();
+ if (ExpressionUtils.isNullLiteral(rhs)) {
+ return VariableAccessUtils.evaluatesToVariable(lhs, variable);
+ }
+ else if (ExpressionUtils.isNullLiteral(lhs)) {
+ return VariableAccessUtils.evaluatesToVariable(rhs, variable);
+ }
+ return false;
+ }
+
+ private static boolean isInSynchronizedContext(PsiElement element) {
+ final PsiSynchronizedStatement syncBlock =
+ PsiTreeUtil.getParentOfType(element,
+ PsiSynchronizedStatement.class);
+ if (syncBlock != null) {
+ return true;
+ }
+ final PsiMethod method =
+ PsiTreeUtil.getParentOfType(element,
+ PsiMethod.class);
+ return method != null &&
+ method.hasModifierProperty(PsiModifier.SYNCHRONIZED)
+ && method.hasModifierProperty(PsiModifier.STATIC);
+ }
+
+ private static boolean isInStaticInitializer(PsiElement element) {
+ final PsiClassInitializer initializer =
+ PsiTreeUtil.getParentOfType(element,
+ PsiClassInitializer.class);
+ return initializer != null &&
+ initializer.hasModifierProperty(PsiModifier.STATIC);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/AnonymousInnerClassMayBeStaticInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/AnonymousInnerClassMayBeStaticInspectionBase.java
deleted file mode 100644
index 4ea6a4c7290f..000000000000
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/AnonymousInnerClassMayBeStaticInspectionBase.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2000-2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.siyeh.ig.j2me;
-
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.siyeh.InspectionGadgetsBundle;
-import com.siyeh.ig.BaseInspection;
-import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.performance.InnerClassReferenceVisitor;
-import org.jetbrains.annotations.NotNull;
-
-public class AnonymousInnerClassMayBeStaticInspectionBase extends BaseInspection {
- @Override
- @NotNull
- public String getDisplayName() {
- return InspectionGadgetsBundle.message(
- "anonymous.inner.may.be.named.static.inner.class.display.name");
- }
-
- @Override
- @NotNull
- public String buildErrorString(Object... infos) {
- return InspectionGadgetsBundle.message(
- "anonymous.inner.may.be.named.static.inner.class.problem.descriptor");
- }
-
- @Override
- public BaseInspectionVisitor buildVisitor() {
- return new AnonymousInnerClassMayBeStaticVisitor();
- }
-
- private static class AnonymousInnerClassMayBeStaticVisitor
- extends BaseInspectionVisitor {
-
- @Override
- public void visitClass(@NotNull PsiClass aClass) {
- if (!(aClass instanceof PsiAnonymousClass)) {
- return;
- }
- if (aClass instanceof PsiEnumConstantInitializer) {
- return;
- }
- final PsiMember containingMember =
- PsiTreeUtil.getParentOfType(aClass, PsiMember.class);
- if (containingMember == null ||
- containingMember.hasModifierProperty(PsiModifier.STATIC)) {
- return;
- }
- final PsiAnonymousClass anAnonymousClass =
- (PsiAnonymousClass)aClass;
- final InnerClassReferenceVisitor visitor =
- new InnerClassReferenceVisitor(anAnonymousClass);
- anAnonymousClass.accept(visitor);
- if (!visitor.canInnerClassBeStatic()) {
- return;
- }
- registerClassError(aClass);
- }
- }
-}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspectionBase.java
index 1305663d7710..dcd737d983fd 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/MissingPackageInfoInspectionBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@ import java.util.List;
/**
* @author Bas Leijdekkers
*/
-public class MissingPackageInfoInspection extends BaseGlobalInspection {
+public class MissingPackageInfoInspectionBase extends BaseGlobalInspection {
@Nls
@NotNull
@@ -105,12 +105,12 @@ public class MissingPackageInfoInspection extends BaseGlobalInspection {
@Nullable
@Override
public LocalInspectionTool getSharedLocalInspectionTool() {
- return new LocalMissingPackageInfoInspection(this);
+ return new LocalMissingPackageInfoInspectionBase(this);
}
- private static class LocalMissingPackageInfoInspection extends BaseSharedLocalInspection<MissingPackageInfoInspection> {
+ protected static class LocalMissingPackageInfoInspectionBase extends BaseSharedLocalInspection<MissingPackageInfoInspectionBase> {
- public LocalMissingPackageInfoInspection(MissingPackageInfoInspection settingsDelegate) {
+ public LocalMissingPackageInfoInspectionBase(MissingPackageInfoInspectionBase settingsDelegate) {
super(settingsDelegate);
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspectionBase.java
new file mode 100644
index 000000000000..974646bdcb2a
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/AnonymousInnerClassMayBeStaticInspectionBase.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.memory;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import org.jetbrains.annotations.NotNull;
+
+public class AnonymousInnerClassMayBeStaticInspectionBase extends BaseInspection {
+ @Override
+ @NotNull
+ public String getDisplayName() {
+ return InspectionGadgetsBundle.message(
+ "anonymous.inner.may.be.named.static.inner.class.display.name");
+ }
+
+ @Override
+ @NotNull
+ public String buildErrorString(Object... infos) {
+ return InspectionGadgetsBundle.message(
+ "anonymous.inner.may.be.named.static.inner.class.problem.descriptor");
+ }
+
+ @Override
+ public BaseInspectionVisitor buildVisitor() {
+ return new AnonymousInnerClassMayBeStaticVisitor();
+ }
+
+ private static class AnonymousInnerClassMayBeStaticVisitor
+ extends BaseInspectionVisitor {
+
+ @Override
+ public void visitAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) {
+ if (anonymousClass instanceof PsiEnumConstantInitializer) {
+ return;
+ }
+ final PsiMember containingMember = PsiTreeUtil.getParentOfType(anonymousClass, PsiMember.class);
+ if (containingMember == null || containingMember.hasModifierProperty(PsiModifier.STATIC)) {
+ return;
+ }
+ final PsiJavaCodeReferenceElement reference = anonymousClass.getBaseClassReference();
+ if (reference.resolve() == null) {
+ // don't warn on broken code
+ return;
+ }
+ final PsiClass containingClass = PsiTreeUtil.getParentOfType(anonymousClass, PsiClass.class);
+ if (containingClass == null) {
+ return;
+ }
+ if (containingClass.getContainingClass() != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
+ // strictly speaking can be named static inner class but not when part of the current containing class
+ return;
+ }
+ final InnerClassReferenceVisitor visitor = new InnerClassReferenceVisitor(anonymousClass);
+ anonymousClass.accept(visitor);
+ if (!visitor.canInnerClassBeStatic()) {
+ return;
+ }
+ if (hasReferenceToLocalClass(anonymousClass)) {
+ return;
+ }
+ registerClassError(anonymousClass);
+ }
+
+ private static boolean hasReferenceToLocalClass(PsiAnonymousClass anonymousClass) {
+ final LocalClassReferenceVisitor visitor = new LocalClassReferenceVisitor();
+ anonymousClass.accept(visitor);
+ return visitor.hasReferenceToLocalClass();
+ }
+
+ private static class LocalClassReferenceVisitor extends JavaRecursiveElementVisitor {
+
+ private boolean referenceToLocalClass = false;
+
+ @Override
+ public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
+ super.visitReferenceElement(reference);
+ if (reference.getQualifier() != null) {
+ return;
+ }
+ final PsiElement target = reference.resolve();
+ if (!(target instanceof PsiClass) || !PsiUtil.isLocalClass((PsiClass)target)) {
+ return;
+ }
+ referenceToLocalClass = true;
+ }
+
+ public boolean hasReferenceToLocalClass() {
+ return referenceToLocalClass;
+ }
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassMayBeStaticInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/InnerClassMayBeStaticInspection.java
index 2599327e4d7d..f588b120b8d5 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassMayBeStaticInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/InnerClassMayBeStaticInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.siyeh.ig.performance;
+package com.siyeh.ig.memory;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInspection.ProblemDescriptor;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/InnerClassReferenceVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/InnerClassReferenceVisitor.java
new file mode 100644
index 000000000000..6f1f817a7735
--- /dev/null
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/memory/InnerClassReferenceVisitor.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ig.memory;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
+import org.jetbrains.annotations.NotNull;
+
+class InnerClassReferenceVisitor extends JavaRecursiveElementVisitor {
+
+ private final PsiClass innerClass;
+ private boolean referencesStaticallyAccessible = true;
+
+ public InnerClassReferenceVisitor(@NotNull PsiClass innerClass) {
+ this.innerClass = innerClass;
+ }
+
+ public boolean canInnerClassBeStatic() {
+ final PsiClass superClass = innerClass.getSuperClass();
+ if (!isClassStaticallyAccessible(superClass)) {
+ return false;
+ }
+ return referencesStaticallyAccessible;
+ }
+
+ private boolean isClassStaticallyAccessible(PsiClass aClass) {
+ if (PsiTreeUtil.isAncestor(innerClass, aClass, false) || aClass.hasModifierProperty(PsiModifier.STATIC)) {
+ return true;
+ }
+ final PsiClass containingClass = aClass.getContainingClass();
+ return containingClass == null || InheritanceUtil.isInheritorOrSelf(innerClass, containingClass, true);
+ }
+
+ @Override
+ public void visitThisExpression(@NotNull PsiThisExpression expression) {
+ if (!referencesStaticallyAccessible) {
+ return;
+ }
+ super.visitThisExpression(expression);
+ if (hasContainingClassQualifier(expression)) {
+ referencesStaticallyAccessible = false;
+ }
+ }
+
+ @Override
+ public void visitSuperExpression(@NotNull PsiSuperExpression expression) {
+ if (!referencesStaticallyAccessible) {
+ return;
+ }
+ super.visitSuperExpression(expression);
+ if (hasContainingClassQualifier(expression)) {
+ referencesStaticallyAccessible = false;
+ }
+ }
+
+ private boolean hasContainingClassQualifier(PsiQualifiedExpression expression) {
+ final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
+ if (qualifier == null) {
+ return false;
+ }
+ return !innerClass.equals(qualifier.resolve());
+ }
+
+ @Override
+ public void visitReferenceExpression(PsiReferenceExpression expression) {
+ if (!referencesStaticallyAccessible) {
+ return;
+ }
+ super.visitReferenceExpression(expression);
+ final PsiExpression qualifierExpression = ParenthesesUtils.stripParentheses(expression.getQualifierExpression());
+ if (qualifierExpression != null) {
+ return;
+ }
+ final PsiElement target = expression.resolve();
+ if (target instanceof PsiLocalVariable || target instanceof PsiParameter) {
+ return;
+ }
+ if (target instanceof PsiMethod || target instanceof PsiField) {
+ final PsiMember member = (PsiMember)target;
+ if (member.hasModifierProperty(PsiModifier.STATIC) || PsiTreeUtil.isAncestor(innerClass, member, true)) {
+ return;
+ }
+ if (!member.hasModifierProperty(PsiModifier.PRIVATE)) {
+ final PsiClass containingClass = member.getContainingClass();
+ if (InheritanceUtil.isInheritorOrSelf(innerClass, containingClass, true)) {
+ return;
+ }
+ }
+ referencesStaticallyAccessible = false;
+ }
+ }
+
+ @Override
+ public void visitNewExpression(PsiNewExpression expression) {
+ if (!referencesStaticallyAccessible) {
+ return;
+ }
+ super.visitNewExpression(expression);
+ final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
+ if (classReference == null) {
+ return;
+ }
+ final PsiElement target = classReference.resolve();
+ if (!(target instanceof PsiClass)) {
+ return;
+ }
+ if (!isClassStaticallyAccessible((PsiClass)target)) {
+ referencesStaticallyAccessible = false;
+ }
+ }
+}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java
deleted file mode 100644
index 45d89b4a4b1d..000000000000
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/InnerClassReferenceVisitor.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.siyeh.ig.performance;
-
-import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.siyeh.ig.psiutils.ClassUtils;
-import org.jetbrains.annotations.NotNull;
-
-public class InnerClassReferenceVisitor extends JavaRecursiveElementVisitor {
-
- private final PsiClass innerClass;
- private boolean referencesStaticallyAccessible = true;
-
- public InnerClassReferenceVisitor(PsiClass innerClass) {
- this.innerClass = innerClass;
- }
-
- public boolean canInnerClassBeStatic() {
- return referencesStaticallyAccessible;
- }
-
- private boolean isClassStaticallyAccessible(PsiClass aClass) {
- if (PsiTreeUtil.isAncestor(innerClass, aClass, false)) {
- return true;
- }
- if (aClass.getContainingClass() != null) {
- return aClass.hasModifierProperty(PsiModifier.STATIC);
- }
- if (InheritanceUtil.isInheritorOrSelf(innerClass, aClass, true)) {
- return true;
- }
- PsiClass classScope = aClass;
- final PsiClass outerClass = ClassUtils.getContainingClass(innerClass);
- while (classScope != null) {
- if (InheritanceUtil.isInheritorOrSelf(outerClass, classScope, true)) {
- return false;
- }
- final PsiElement scope = classScope.getScope();
- if (scope instanceof PsiClass) {
- classScope = (PsiClass)scope;
- }
- else {
- classScope = null;
- }
- }
- return true;
- }
-
- @Override
- public void visitThisExpression(@NotNull PsiThisExpression expression) {
- if (!referencesStaticallyAccessible) {
- return;
- }
- super.visitThisExpression(expression);
- if (hasContainingClassQualifier(expression)) {
- referencesStaticallyAccessible = false;
- }
- }
-
- @Override
- public void visitSuperExpression(@NotNull PsiSuperExpression expression) {
- if (!referencesStaticallyAccessible) {
- return;
- }
- super.visitSuperExpression(expression);
- if (hasContainingClassQualifier(expression)) {
- referencesStaticallyAccessible = false;
- }
- }
-
- private boolean hasContainingClassQualifier(PsiQualifiedExpression expression) {
- final PsiJavaCodeReferenceElement qualifier = expression.getQualifier();
- if (qualifier == null) {
- return false;
- }
- final PsiElement element = qualifier.resolve();
- if (!(element instanceof PsiClass)) {
- return false;
- }
- final PsiClass aClass = (PsiClass)element;
- return !aClass.equals(innerClass);
- }
-
- @Override
- public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) {
- if (!referencesStaticallyAccessible) {
- return;
- }
- final PsiElement parent = reference.getParent();
- if (parent instanceof PsiThisExpression || parent instanceof PsiSuperExpression) {
- return;
- }
- super.visitReferenceElement(reference);
-
- final PsiElement qualifier = reference.getQualifier();
- if (qualifier instanceof PsiSuperExpression) {
- return;
- }
- if (qualifier instanceof PsiReferenceExpression) {
- final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
- final PsiElement resolvedExpression = referenceExpression.resolve();
- if (!(resolvedExpression instanceof PsiField) && !(resolvedExpression instanceof PsiMethod)) {
- return;
- }
- }
- final PsiElement element = reference.resolve();
- if (element instanceof PsiMethod || element instanceof PsiField) {
- final PsiMember member = (PsiMember)element;
- if (member.hasModifierProperty(PsiModifier.STATIC)) {
- return;
- }
- final PsiClass containingClass = member.getContainingClass();
- if (innerClass.equals(containingClass)) {
- return;
- }
- if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
- referencesStaticallyAccessible = false;
- return;
- }
- referencesStaticallyAccessible &= isClassStaticallyAccessible(containingClass);
- }
- else if (element instanceof PsiLocalVariable || element instanceof PsiParameter) {
- final PsiElement containingMethod = PsiTreeUtil.getParentOfType(reference, PsiMethod.class);
- final PsiElement referencedMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
- if (containingMethod != null && referencedMethod != null && !containingMethod.equals(referencedMethod)) {
- referencesStaticallyAccessible = false;
- }
- }
- else if (element instanceof PsiClass) {
- final PsiClass aClass = (PsiClass)element;
- referencesStaticallyAccessible &= isClassStaticallyAccessible(aClass);
- }
- }
-}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java
index 40daa3332896..4656d0c4610a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java
@@ -19,6 +19,7 @@ import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
@@ -80,7 +81,7 @@ public class ClassUtils {
private ClassUtils() {}
@Nullable
- public static PsiClass findClass(String fqClassName, PsiElement context) {
+ public static PsiClass findClass(@NonNls String fqClassName, PsiElement context) {
return JavaPsiFacade.getInstance(context.getProject()).findClass(fqClassName, context.getResolveScope());
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java
index fc6d2580b3e9..242bec97a398 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2013 Bas Leijdekkers
+ * Copyright 2005-2014 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -198,11 +198,8 @@ public class ExpressionUtils {
}
public static boolean isNullLiteral(@Nullable PsiExpression expression) {
- if (!(expression instanceof PsiLiteralExpression)) {
- return false;
- }
- final String text = expression.getText();
- return PsiKeyword.NULL.equals(text);
+ expression = ParenthesesUtils.stripParentheses(expression);
+ return expression != null && PsiType.NULL.equals(expression.getType());
}
public static boolean isZero(@Nullable PsiExpression expression) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java
index e4e91685878b..fca66288aaef 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/CStyleArrayDeclarationInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,20 +16,24 @@
package com.siyeh.ig.style;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiTypeElement;
-import com.intellij.psi.PsiVariable;
-import com.intellij.util.IncorrectOperationException;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.tree.IElementType;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
public class CStyleArrayDeclarationInspection extends BaseInspection {
+ public boolean ignoreVariables = false;
+
@Override
@NotNull
public String getDisplayName() {
@@ -40,8 +44,18 @@ public class CStyleArrayDeclarationInspection extends BaseInspection {
@Override
@NotNull
protected String buildErrorString(Object... infos) {
- return InspectionGadgetsBundle.message(
- "c.style.array.declaration.problem.descriptor");
+ final Object info = infos[0];
+ if (info instanceof PsiMethod) {
+ return InspectionGadgetsBundle.message("cstyle.array.method.declaration.problem.descriptor");
+ }
+ final int choice = info instanceof PsiField ? 1 : info instanceof PsiParameter ? 2 : 3;
+ return InspectionGadgetsBundle.message("cstyle.array.variable.declaration.problem.descriptor", Integer.valueOf(choice));
+ }
+
+ @Nullable
+ @Override
+ public JComponent createOptionsPanel() {
+ return new SingleCheckboxOptionsPanel("Ignore C-style declarations in variables", this, "ignoreVariables");
}
@Override
@@ -65,12 +79,38 @@ public class CStyleArrayDeclarationInspection extends BaseInspection {
}
@Override
- public void doFix(Project project, ProblemDescriptor descriptor)
- throws IncorrectOperationException {
- final PsiElement nameElement = descriptor.getPsiElement();
- final PsiVariable var = (PsiVariable)nameElement.getParent();
- assert var != null;
- var.normalizeDeclaration();
+ public void doFix(Project project, ProblemDescriptor descriptor) {
+ final PsiElement element = descriptor.getPsiElement().getParent();
+ if (element instanceof PsiVariable) {
+ final PsiVariable variable = (PsiVariable)element;
+ variable.normalizeDeclaration();
+ CodeStyleManager.getInstance(project).reformat(variable);
+ }
+ else if (element instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)element;
+ final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
+ if (returnTypeElement == null) {
+ return;
+ }
+ final PsiType returnType = method.getReturnType();
+ if (returnType == null) {
+ return;
+ }
+ PsiElement child = method.getParameterList();
+ while (!(child instanceof PsiCodeBlock)) {
+ final PsiElement element1 = child;
+ child = child.getNextSibling();
+ if (element1 instanceof PsiJavaToken) {
+ final PsiJavaToken token = (PsiJavaToken)element1;
+ final IElementType tokenType = token.getTokenType();
+ if (JavaTokenType.LBRACKET.equals(tokenType) || JavaTokenType.RBRACKET.equals(tokenType)) {
+ token.delete();
+ }
+ }
+ }
+ final PsiTypeElement typeElement = JavaPsiFacade.getElementFactory(project).createTypeElement(returnType);
+ returnTypeElement.replace(typeElement);
+ }
}
}
@@ -79,17 +119,19 @@ public class CStyleArrayDeclarationInspection extends BaseInspection {
return new CStyleArrayDeclarationVisitor();
}
- private static class CStyleArrayDeclarationVisitor
- extends BaseInspectionVisitor {
+ private class CStyleArrayDeclarationVisitor extends BaseInspectionVisitor {
@Override
- public void visitVariable(@NotNull PsiVariable var) {
- super.visitVariable(var);
- final PsiType declaredType = var.getType();
+ public void visitVariable(@NotNull PsiVariable variable) {
+ super.visitVariable(variable);
+ if (ignoreVariables) {
+ return;
+ }
+ final PsiType declaredType = variable.getType();
if (declaredType.getArrayDimensions() == 0) {
return;
}
- final PsiTypeElement typeElement = var.getTypeElement();
+ final PsiTypeElement typeElement = variable.getTypeElement();
if (typeElement == null) {
return; // Could be true for enum constants.
}
@@ -97,7 +139,25 @@ public class CStyleArrayDeclarationInspection extends BaseInspection {
if (elementType.equals(declaredType)) {
return;
}
- registerVariableError(var);
+ registerVariableError(variable, variable);
+ }
+
+ @Override
+ public void visitMethod(PsiMethod method) {
+ super.visitMethod(method);
+ final PsiType returnType = method.getReturnType();
+ if (returnType == null || returnType.getArrayDimensions() == 0) {
+ return;
+ }
+ final PsiTypeElement typeElement = method.getReturnTypeElement();
+ if (typeElement == null) {
+ return;
+ }
+ final PsiType type = typeElement.getType();
+ if (type.equals(returnType)) {
+ return;
+ }
+ registerMethodError(method, method);
}
}
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/NestedMethodCallInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/NestedMethodCallInspectionBase.java
index 484c1f8fefe0..57659d05923a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/NestedMethodCallInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/NestedMethodCallInspectionBase.java
@@ -16,6 +16,7 @@
package com.siyeh.ig.style;
import com.intellij.psi.*;
+import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
@@ -29,6 +30,12 @@ public class NestedMethodCallInspectionBase extends BaseInspection {
*/
public boolean m_ignoreFieldInitializations = true;
+ @SuppressWarnings("PublicField")
+ public boolean ignoreStaticMethods = false;
+
+ @SuppressWarnings("PublicField")
+ public boolean ignoreGetterCalls = false;
+
@Override
@NotNull
public String getDisplayName() {
@@ -82,6 +89,18 @@ public class NestedMethodCallInspectionBase extends BaseInspection {
return;
}
}
+ final PsiMethod method = expression.resolveMethod();
+ if (method == null) {
+ return;
+ }
+ if (ignoreStaticMethods || ignoreGetterCalls) {
+ if (ignoreStaticMethods && method.hasModifierProperty(PsiModifier.STATIC)) {
+ return;
+ }
+ if (ignoreGetterCalls && PropertyUtil.isSimpleGetter(method)) {
+ return;
+ }
+ }
registerMethodCallError(expression);
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java
index 0036f4a41f99..d9f5242d3ab6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/DoubleCheckedLockingInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
-import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -74,17 +73,16 @@ public class DoubleCheckedLockingInspection extends BaseInspection {
private static class DoubleCheckedLockingFix extends InspectionGadgetsFix {
- private final PsiField field;
+ private final String myFieldName;
private DoubleCheckedLockingFix(PsiField field) {
- this.field = field;
+ myFieldName = field.getName();
}
@Override
@NotNull
public String getName() {
- return InspectionGadgetsBundle.message(
- "double.checked.locking.quickfix", field.getName());
+ return InspectionGadgetsBundle.message("double.checked.locking.quickfix", myFieldName);
}
@NotNull
@@ -94,8 +92,21 @@ public class DoubleCheckedLockingInspection extends BaseInspection {
}
@Override
- protected void doFix(Project project, ProblemDescriptor descriptor)
- throws IncorrectOperationException {
+ protected void doFix(Project project, ProblemDescriptor descriptor) {
+ final PsiElement element = descriptor.getPsiElement();
+ final PsiElement parent = element.getParent();
+ if (!(parent instanceof PsiIfStatement)) {
+ return;
+ }
+ final PsiIfStatement ifStatement = (PsiIfStatement)parent;
+ final PsiExpression condition = ifStatement.getCondition();
+ if (condition == null) {
+ return;
+ }
+ final PsiField field = findCheckedField(condition);
+ if (field == null) {
+ return;
+ }
final PsiModifierList modifierList = field.getModifierList();
if (modifierList == null) {
return;
@@ -104,13 +115,55 @@ public class DoubleCheckedLockingInspection extends BaseInspection {
}
}
+ @Nullable
+ private static PsiField findCheckedField(PsiExpression expression) {
+ if (expression instanceof PsiReferenceExpression) {
+ final PsiReferenceExpression referenceExpression =
+ (PsiReferenceExpression)expression;
+ final PsiElement target = referenceExpression.resolve();
+ if (!(target instanceof PsiField)) {
+ return null;
+ }
+ return (PsiField)target;
+ }
+ else if (expression instanceof PsiBinaryExpression) {
+ final PsiBinaryExpression binaryExpression =
+ (PsiBinaryExpression)expression;
+ final IElementType tokenType =
+ binaryExpression.getOperationTokenType();
+ if (!JavaTokenType.EQEQ.equals(tokenType)
+ && !JavaTokenType.NE.equals(tokenType)) {
+ return null;
+ }
+ final PsiExpression lhs = binaryExpression.getLOperand();
+ final PsiExpression rhs = binaryExpression.getROperand();
+ final PsiField field = findCheckedField(lhs);
+ if (field != null) {
+ return field;
+ }
+ return findCheckedField(rhs);
+ }
+ else if (expression instanceof PsiPrefixExpression) {
+ final PsiPrefixExpression prefixExpression =
+ (PsiPrefixExpression)expression;
+ final IElementType tokenType =
+ prefixExpression.getOperationTokenType();
+ if (!JavaTokenType.EXCL.equals(tokenType)) {
+ return null;
+ }
+ return findCheckedField(prefixExpression.getOperand());
+ }
+ else {
+ return null;
+ }
+ }
+
@Override
public BaseInspectionVisitor buildVisitor() {
return new DoubleCheckedLockingVisitor();
}
- private class DoubleCheckedLockingVisitor
- extends BaseInspectionVisitor {
+ private class DoubleCheckedLockingVisitor extends BaseInspectionVisitor {
@Override
public void visitIfStatement(
@@ -161,48 +214,5 @@ public class DoubleCheckedLockingInspection extends BaseInspection {
}
registerStatementError(statement, field);
}
-
- @Nullable
- private PsiField findCheckedField(PsiExpression expression) {
- if (expression instanceof PsiReferenceExpression) {
- final PsiReferenceExpression referenceExpression =
- (PsiReferenceExpression)expression;
- final PsiElement target = referenceExpression.resolve();
- if (!(target instanceof PsiField)) {
- return null;
- }
- return (PsiField)target;
- }
- else if (expression instanceof PsiBinaryExpression) {
- final PsiBinaryExpression binaryExpression =
- (PsiBinaryExpression)expression;
- final IElementType tokenType =
- binaryExpression.getOperationTokenType();
- if (!JavaTokenType.EQEQ.equals(tokenType)
- && !JavaTokenType.NE.equals(tokenType)) {
- return null;
- }
- final PsiExpression lhs = binaryExpression.getLOperand();
- final PsiExpression rhs = binaryExpression.getROperand();
- final PsiField field = findCheckedField(lhs);
- if (field != null) {
- return field;
- }
- return findCheckedField(rhs);
- }
- else if (expression instanceof PsiPrefixExpression) {
- final PsiPrefixExpression prefixExpression =
- (PsiPrefixExpression)expression;
- final IElementType tokenType =
- prefixExpression.getOperationTokenType();
- if (!JavaTokenType.EXCL.equals(tokenType)) {
- return null;
- }
- return findCheckedField(prefixExpression.getOperand());
- }
- else {
- return null;
- }
- }
}
} \ No newline at end of file