Merge remote-tracking branch 'origin/master'

This commit is contained in:
Yann Cébron
2014-08-28 12:57:15 +02:00
30 changed files with 401 additions and 167 deletions
@@ -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.
@@ -57,6 +57,9 @@ public abstract class BaseClassesAnalysisAction extends BaseAnalysisAction {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (project.isDisposed()) {
return;
}
if (!upToDate) {
final int i = Messages.showYesNoCancelDialog(getProject(), AnalysisScopeBundle.message("recompile.confirmation.message"),
AnalysisScopeBundle.message("project.is.out.of.date"), Messages.getWarningIcon());
@@ -15,10 +15,12 @@
*/
package com.intellij.psi.impl.source.resolve.graphInference;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.resolve.graphInference.constraints.*;
@@ -42,6 +44,12 @@ public class InferenceSession {
public static final Key<PsiType> LOWER_BOUND = Key.create("LowBound");
private static final Key<Boolean> ERASED = Key.create("UNCHECKED_CONVERSION");
private static final Function<Pair<PsiType, PsiType>, PsiType> UPPER_BOUND_FUNCTION = new Function<Pair<PsiType, PsiType>, PsiType>() {
@Override
public PsiType fun(Pair<PsiType, PsiType> pair) {
return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
}
};
private final Set<InferenceVariable> myInferenceVariables = new LinkedHashSet<InferenceVariable>();
private final List<ConstraintFormula> myConstraints = new ArrayList<ConstraintFormula>();
@@ -359,9 +367,7 @@ public class InferenceSession {
final PsiClassType[] extendsListTypes = parameter.getExtendsListTypes();
for (PsiType classType : extendsListTypes) {
classType = substituteWithInferenceVariables(mySiteSubstitutor.substitute(classType));
HashSet<InferenceVariable> dependencies = new HashSet<InferenceVariable>();
collectDependencies(classType, dependencies);//todo isProperType
if (dependencies.isEmpty() || dependencies.size() == 1 && dependencies.contains(variable)) {
if (isProperType(classType)) {
added = true;
}
variable.addBound(classType, InferenceBound.UPPER);
@@ -681,7 +687,13 @@ public class InferenceSession {
while (!allVars.isEmpty()) {
final List<InferenceVariable> vars = InferenceVariablesOrder.resolveOrder(allVars, this);
if (!myIncorporationPhase.hasCaptureConstraints(vars)) {
final PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor);
PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor);
if (firstSubstitutor != null) {
final Set<PsiTypeParameter> parameters = firstSubstitutor.getSubstitutionMap().keySet();
if (GenericsUtil.findTypeParameterWithBoundError(parameters.toArray(new PsiTypeParameter[parameters.size()]), firstSubstitutor, myContext, true) != null) {
firstSubstitutor = null;
}
}
if (firstSubstitutor != null) {
substitutor = firstSubstitutor;
allVars.removeAll(vars);
@@ -690,19 +702,20 @@ public class InferenceSession {
}
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getManager().getProject());
for (InferenceVariable var : vars) {
final PsiTypeParameter parameter = var.getParameter();
final PsiTypeParameter copy = elementFactory.createTypeParameterFromText("z" + parameter.getName(), null);
final PsiType lub = getLowerBound(var, substitutor);
final PsiType glb = getUpperBound(var, substitutor);
//todo add upper bound to the fresh type variable
final PsiTypeParameter[] freshParameters = createFreshVariables(vars);
for (int i = 0; i < freshParameters.length; i++) {
PsiTypeParameter parameter = freshParameters[i];
final InferenceVariable var = vars.get(i);
final PsiType lub = getLowerBound(var, PsiSubstitutor.EMPTY);
if (lub != PsiType.NULL) {
if (!TypeConversionUtil.isAssignable(glb, lub)) {
return null;
for (PsiClassType upperBoundType : parameter.getExtendsListTypes()) {
if (!TypeConversionUtil.isAssignable(upperBoundType, lub)) {
return null;
}
}
copy.putUserData(LOWER_BOUND, lub);
parameter.putUserData(LOWER_BOUND, lub);
}
var.addBound(elementFactory.createType(copy), InferenceBound.EQ);
var.addBound(elementFactory.createType(parameter), InferenceBound.EQ);
}
myIncorporationPhase.forgetCaptures(vars);
if (!repeatInferencePhases(true)) {
@@ -712,13 +725,38 @@ public class InferenceSession {
return substitutor;
}
private PsiType getLowerBound(InferenceVariable var, PsiSubstitutor substitutor) {
return composeBound(var, InferenceBound.LOWER, new Function<Pair<PsiType, PsiType>, PsiType>() {
private PsiTypeParameter[] createFreshVariables(final List<InferenceVariable> vars) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(getManager().getProject());
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
final PsiTypeParameter[] yVars = new PsiTypeParameter[vars.size()];
for (int i = 0; i < vars.size(); i++) {
InferenceVariable var = vars.get(i);
final PsiTypeParameter parameter = var.getParameter();
yVars[i] = elementFactory.createTypeParameterFromText(getFreshVariableName(var), parameter);
substitutor = substitutor.put(var, elementFactory.createType(yVars[i]));
}
final PsiSubstitutor ySubstitutor = substitutor;
final String classText = "class I<" + StringUtil.join(vars, new Function<InferenceVariable, String>() {
@Override
public PsiType fun(Pair<PsiType, PsiType> pair) {
return GenericsUtil.getLeastUpperBound(pair.first, pair.second, myManager);
public String fun(InferenceVariable variable) {
final PsiType glb = composeBound(variable, InferenceBound.UPPER, UPPER_BOUND_FUNCTION, ySubstitutor, true);
return getFreshVariableName(variable) + " extends " + glb.getInternalCanonicalText();
}
}, substitutor);
}, ", ") + ">{}";
final PsiFile file =
PsiFileFactory.getInstance(getManager().getProject()).createFileFromText("inference_dummy.java", JavaFileType.INSTANCE, classText);
LOG.assertTrue(file instanceof PsiJavaFile, classText);
final PsiClass[] classes = ((PsiJavaFile)file).getClasses();
LOG.assertTrue(classes.length == 1, classText);
return classes[0].getTypeParameters();
}
private static String getFreshVariableName(InferenceVariable var) {
return var.getName();
}
private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor) {
@@ -747,15 +785,19 @@ public class InferenceSession {
return substitutor;
}
private PsiType getUpperBound(InferenceVariable var, PsiSubstitutor substitutor) {
return composeBound(var, InferenceBound.UPPER, new Function<Pair<PsiType, PsiType>, PsiType>() {
private PsiType getLowerBound(InferenceVariable var, PsiSubstitutor substitutor) {
return composeBound(var, InferenceBound.LOWER, new Function<Pair<PsiType, PsiType>, PsiType>() {
@Override
public PsiType fun(Pair<PsiType, PsiType> pair) {
return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
return GenericsUtil.getLeastUpperBound(pair.first, pair.second, myManager);
}
}, substitutor);
}
private PsiType getUpperBound(InferenceVariable var, PsiSubstitutor substitutor) {
return composeBound(var, InferenceBound.UPPER, UPPER_BOUND_FUNCTION, substitutor);
}
public PsiType getEqualsBound(InferenceVariable var, PsiSubstitutor substitutor) {
return composeBound(var, InferenceBound.EQ, new Function<Pair<PsiType, PsiType>, PsiType>() {
@Override
@@ -769,11 +811,19 @@ public class InferenceSession {
InferenceBound boundType,
Function<Pair<PsiType, PsiType>, PsiType> fun,
PsiSubstitutor substitutor) {
return composeBound(variable, boundType, fun, substitutor, false);
}
private PsiType composeBound(InferenceVariable variable,
InferenceBound boundType,
Function<Pair<PsiType, PsiType>, PsiType> fun,
PsiSubstitutor substitutor,
boolean includeNonProperBounds) {
final List<PsiType> lowerBounds = variable.getBounds(boundType);
PsiType lub = PsiType.NULL;
for (PsiType lowerBound : lowerBounds) {
lowerBound = substituteNonProperBound(lowerBound, substitutor);
if (isProperType(lowerBound)) {
if (includeNonProperBounds || isProperType(lowerBound)) {
if (lub == PsiType.NULL) {
lub = lowerBound;
}
@@ -1,7 +1,16 @@
import java.util.List;
class Sample {
<T extends List<K>, K extends List<T>> void foo(){}
<T extends List<K>, K extends List<T>> T foo(){
<error descr="Incompatible types. Found: 'K', required: 'T'">T t = foo().get(0);</error>
<error descr="Incompatible types. Found: 'K', required: 'K'">K k = foo().get(0);</error>
<error descr="Incompatible types. Found: 'T', required: 'T'">T t1 = foo().get(0).get(0);</error>
String s = foo();
<error descr="Incompatible types. Found: 'K', required: 'java.lang.String'">String s1 = foo().get(0);</error>
return null;
}
{
foo();
@@ -3,5 +3,5 @@ import java.util.Map;
public class SOE {
public static <K extends M, M extends Map<K,M>> M foo() {return null;}
public static <K1 extends M1, M1 extends Map<K1,M1>> Map<K1, M1> foo1() {return <error descr="Inferred type 'java.util.Map<K1,M1>' for type parameter 'M' is not within its bound; should implement 'java.util.Map<java.util.Map<K1,M1>,java.util.Map<K1,M1>>'">foo()</error>;}
public static <K1 extends M1, M1 extends Map<K1,M1>> Map<K1, M1> foo1() {<error descr="Incompatible types. Found: 'M', required: 'java.util.Map<K1,M1>'">return foo();</error>}
}
@@ -57,7 +57,6 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
doTest();
}
@Bombed(day = 30, month = Calendar.AUGUST)
public void testCyclicParamsDependency() throws Exception {
doTest();
}
@@ -56,6 +56,7 @@ public class SearchCommand {
}
public void matchingFinished() {
if (project.isDisposed()) return;
findEnded();
progress.setText(SSRBundle.message("found.progress.message", count));
}
@@ -132,9 +133,7 @@ public class SearchCommand {
}
protected void findEnded() {
if (!project.isDisposed()) {
StructuralSearchPlugin.getInstance(project).setSearchInProgress(false);
}
StructuralSearchPlugin.getInstance(project).setSearchInProgress(false);
}
protected void foundUsage(MatchResult result, Usage usage) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 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.
@@ -25,6 +25,7 @@ import com.siyeh.ig.DelegatingFix;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.TestUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -71,70 +72,45 @@ public class JUnit3StyleTestMethodInJUnit4ClassInspection extends BaseInspection
if (!name.startsWith("test")) {
return;
}
if (method.hasModifierProperty(PsiModifier.ABSTRACT) || !method.hasModifierProperty(PsiModifier.PUBLIC)) {
if (!TestUtils.isRunnable(method)) {
return;
}
if (TestUtils.isJUnit4TestMethod(method)) {
return;
}
final PsiType returnType = method.getReturnType();
if (returnType == null || !returnType.equals(PsiType.VOID)) {
return;
}
final PsiParameterList parameterList = method.getParameterList();
if (parameterList.getParametersCount() != 0) {
return;
}
final PsiClass containingClass = method.getContainingClass();
if (TestUtils.isJUnitTestClass(containingClass)) {
return;
}
if (!containsReferenceToClass(containingClass, "org.junit.Test")) {
if (!containsJUnit4Annotation(containingClass)) {
return;
}
registerMethodError(method);
}
}
public static boolean containsReferenceToClass(PsiElement element, String fullyQualifiedName) {
final ClassReferenceVisitor visitor = new ClassReferenceVisitor(fullyQualifiedName);
public static boolean containsJUnit4Annotation(PsiElement element) {
final JUnit4AnnotationVisitor visitor = new JUnit4AnnotationVisitor();
element.accept(visitor);
return visitor.isReferenceFound();
return visitor.isJUnit4AnnotationFound();
}
private static class ClassReferenceVisitor extends JavaRecursiveElementVisitor {
private static class JUnit4AnnotationVisitor extends JavaRecursiveElementWalkingVisitor {
private final String fullyQualifiedName;
private boolean referenceFound = false;
private ClassReferenceVisitor(String fullyQualifiedName) {
this.fullyQualifiedName = fullyQualifiedName;
}
private boolean myJUnit4AnnotationFound = false;
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
super.visitReferenceElement(reference);
if (referenceFound) {
public void visitAnnotation(PsiAnnotation annotation) {
super.visitAnnotation(annotation);
@NonNls final String qualifiedName = annotation.getQualifiedName();
if (qualifiedName == null || !qualifiedName.startsWith("org.junit.")) {
return;
}
if (!(reference.getParent() instanceof PsiAnnotation)) {
// optimization
return;
}
final PsiElement element = reference.resolve();
if (!(element instanceof PsiClass) || element instanceof PsiTypeParameter) {
return;
}
final PsiClass aClass = (PsiClass)element;
final String classQualifiedName = aClass.getQualifiedName();
if (classQualifiedName == null || !classQualifiedName.equals(fullyQualifiedName)) {
return;
}
referenceFound = true;
myJUnit4AnnotationFound = true;
}
public boolean isReferenceFound() {
return referenceFound;
public boolean isJUnit4AnnotationFound() {
return myJUnit4AnnotationFound;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2011 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.
@@ -15,14 +15,14 @@
*/
package com.siyeh.ig.junit;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiParameterList;
import com.intellij.psi.PsiType;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.TestUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class TestMethodIsPublicVoidNoArgInspection extends BaseInspection {
@@ -70,23 +70,20 @@ public class TestMethodIsPublicVoidNoArgInspection extends BaseInspection {
@Override
public void visitMethod(@NotNull PsiMethod method) {
//note: no call to super;
@NonNls final String methodName = method.getName();
if (!methodName.startsWith("test") &&
!TestUtils.isJUnit4TestMethod(method)) {
if (method.isConstructor()) {
return;
}
if (!TestUtils.isJUnit3TestMethod(method) && !TestUtils.isJUnit4TestMethod(method)) {
return;
}
final PsiType returnType = method.getReturnType();
if (returnType == null) {
return;
}
final PsiParameterList parameterList = method.getParameterList();
final boolean takesArguments;
final boolean isStatic;
if (parameterList.getParametersCount() == 0) {
takesArguments = false;
isStatic = method.hasModifierProperty(PsiModifier.STATIC);
if (!isStatic && returnType.equals(PsiType.VOID) &&
method.hasModifierProperty(PsiModifier.PUBLIC)) {
if (!isStatic && PsiType.VOID.equals(returnType) && method.hasModifierProperty(PsiModifier.PUBLIC)) {
return;
}
}
@@ -94,14 +91,6 @@ public class TestMethodIsPublicVoidNoArgInspection extends BaseInspection {
isStatic = false;
takesArguments = true;
}
final PsiClass targetClass = method.getContainingClass();
if (!AnnotationUtil.isAnnotated(method, "org.junit.Test", true)) {
if (targetClass == null ||
!InheritanceUtil.isInheritor(targetClass,
"junit.framework.TestCase")) {
return;
}
}
registerMethodError(method, Boolean.valueOf(takesArguments),
Boolean.valueOf(isStatic));
}
@@ -18,22 +18,16 @@ package com.siyeh.ig.naming;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.util.ui.CheckBox;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.LibraryUtil;
import com.siyeh.ig.psiutils.MethodUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class InstanceMethodNamingConventionInspectionBase extends ConventionInspection {
private static final int DEFAULT_MIN_LENGTH = 4;
private static final int DEFAULT_MAX_LENGTH = 32;
@SuppressWarnings("PublicField")
public boolean ignoreNativeMethods = true;
@Override
@NotNull
public String getDisplayName() {
@@ -58,13 +52,6 @@ public class InstanceMethodNamingConventionInspectionBase extends ConventionInsp
return InspectionGadgetsBundle.message("instance.method.name.convention.problem.descriptor.regex.mismatch", getRegex());
}
@Override
public JComponent[] createExtraOptions() {
return new JComponent[] {
new CheckBox("ignore 'native' methods", this, "ignoreNativeMethods")
};
}
@Override
protected String getDefaultRegex() {
return "[a-z][A-Za-z\\d]*";
@@ -93,7 +80,7 @@ public class InstanceMethodNamingConventionInspectionBase extends ConventionInsp
if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
if (ignoreNativeMethods && method.hasModifierProperty(PsiModifier.NATIVE)) {
if (method.hasModifierProperty(PsiModifier.NATIVE) && isInspectionEnabled("NativeMethodNamingConvention", method)) {
return;
}
final PsiIdentifier nameIdentifier = method.getNameIdentifier();
@@ -77,7 +77,7 @@ public class NativeMethodNamingConventionInspectionBase extends ConventionInspec
@Override
public void visitMethod(@NotNull PsiMethod method) {
super.visitMethod(method);
if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) {
if (method.isConstructor()) {
return;
}
if (!method.hasModifierProperty(PsiModifier.NATIVE)) {
@@ -17,20 +17,14 @@ package com.siyeh.ig.naming;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.util.ui.CheckBox;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspectionVisitor;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class StaticMethodNamingConventionInspectionBase extends ConventionInspection {
private static final int DEFAULT_MIN_LENGTH = 4;
private static final int DEFAULT_MAX_LENGTH = 32;
@SuppressWarnings("PublicField")
public boolean ignoreNativeMethods = true;
@Override
@NotNull
public String getDisplayName() {
@@ -60,13 +54,6 @@ public class StaticMethodNamingConventionInspectionBase extends ConventionInspec
getRegex());
}
@Override
public JComponent[] createExtraOptions() {
return new JComponent[]{
new CheckBox("ignore 'native' methods", this, "ignoreNativeMethods")
};
}
@Override
protected String getDefaultRegex() {
return "[a-z][A-Za-z\\d]*";
@@ -95,7 +82,7 @@ public class StaticMethodNamingConventionInspectionBase extends ConventionInspec
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
return;
}
if (ignoreNativeMethods && method.hasModifierProperty(PsiModifier.NATIVE)) {
if (method.hasModifierProperty(PsiModifier.NATIVE) && isInspectionEnabled("NativeMethodNamingConvention", method)) {
return;
}
final String name = method.getName();
@@ -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.
@@ -22,8 +22,8 @@ import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,34 +66,37 @@ public class TestUtils {
}
public static boolean isJUnitTestMethod(@Nullable PsiMethod method) {
return isRunnable(method) && (isJUnit3TestMethod(method) || isJUnit4TestMethod(method));
}
public static boolean isRunnable(PsiMethod method) {
if (method == null) {
return false;
}
if (isJUnit4TestMethod(method)) {
return true;
if (method.hasModifierProperty(PsiModifier.ABSTRACT) ||
method.hasModifierProperty(PsiModifier.STATIC) ||
!method.hasModifierProperty(PsiModifier.PUBLIC)) {
return false;
}
final PsiType returnType = method.getReturnType();
if (!PsiType.VOID.equals(returnType)) {
return false;
}
final PsiParameterList parameterList = method.getParameterList();
return parameterList.getParametersCount() == 0;
}
public static boolean isJUnit3TestMethod(@Nullable PsiMethod method) {
if (method == null) {
return false;
}
final String methodName = method.getName();
@NonNls final String test = "test";
if (!methodName.startsWith(test)) {
return false;
}
if (method.hasModifierProperty(PsiModifier.ABSTRACT) ||
!method.hasModifierProperty(PsiModifier.PUBLIC)) {
return false;
}
final PsiType returnType = method.getReturnType();
if (returnType == null) {
return false;
}
if (!returnType.equals(PsiType.VOID)) {
return false;
}
final PsiParameterList parameterList = method.getParameterList();
if (parameterList.getParametersCount() != 0) {
return false;
}
final PsiClass targetClass = method.getContainingClass();
return isJUnitTestClass(targetClass);
final PsiClass containingClass = method.getContainingClass();
return isJUnitTestClass(containingClass);
}
public static boolean isJUnit4TestMethod(@Nullable PsiMethod method) {
@@ -8,8 +8,6 @@ methods are ignored by this inspection.
Use the fields below to specify minimum length, maximum length and regular expression expected for instance method names.
Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
<p>
Use the checkbox below to ignore native methods.
<p>
</body>
</html>
@@ -1,11 +1,13 @@
<html>
<body>
Reports 'native' methods whose names are either too short, too long, or do not follow
Reports <b>native</b> methods whose names are either too short, too long, or do not follow
the specified regular expression pattern. Methods that override library
methods are ignored by this inspection.
When this inspection is enabled, the <i>Instance method naming convention</i> and
<i>'static' method naming convention</i> inspections will ignore <b>native</b> methods automatically.
<!-- tooltip end -->
<p>
Use the fields below to specify minimum length, maximum length and regular expression expected for 'native' method names.
Use the fields below to specify minimum length, maximum length and regular expression expected for <b>native</b> method names.
Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
<p>
<small>New in 14</small>
@@ -7,8 +7,6 @@ the specified regular expression pattern.
Use the fields below to specify minimum length, maximum length and regular expression expected for static method names.
Specify <b>0</b> to not check the length of names. Regular expressions are in standard <b>java.util.regex</b> format.
<p>
Use the checkbox below to ignore native methods.
<p>
</body>
</html>
@@ -1,8 +1,8 @@
<html>
<body>
Reports any JUnit test methods whose names which are not declared
Reports any JUnit test methods which are declared <b>static</b>, not declared
<b>public</b>, do not return
<b>void</b>, or take arguments.
<b>void</b>, or have parameters.
Such test methods are easy to create inadvertently, but will not be executed by
JUnit test runners.
<!-- tooltip end -->
@@ -1,15 +0,0 @@
package com.siyeh.igtest.junit;
import junit.framework.TestCase;
public class TestCaseWithNoTestMethodsInspection extends TestCase
{
public TestCaseWithNoTestMethodsInspection()
{
}
public void teardown()
{
}
}
@@ -0,0 +1,9 @@
import org.junit.Before;
public class BeforeAnnotationUsed {
@Before
public void before() {}
public void <warning descr="Old style JUnit test method 'testOldStyle()' in JUnit 4 class">testOldStyle</warning>() {}
}
@@ -0,0 +1,10 @@
import org.junit.Test;
public class JUnit3StyleTestMethodInJUnit4Class {
@Test
public void junit4Test() {
}
public void <warning descr="Old style JUnit test method 'testJUnit3()' in JUnit 4 class">testJUnit3</warning>() {}
}
@@ -0,0 +1,19 @@
public class <warning descr="JUnit test case 'TestCaseWithNoTestMethods' has no tests">TestCaseWithNoTestMethods</warning> extends junit.framework.TestCase {
TestCaseWithNoTestMethods() {}
public int testOne() {
return 1;
}
public static void testTwo() {}
void testThree() {}
public void testFour(int i) {}
public void setUp() throws Exception {
super.setUp();
}
public void tearDown() throws Exception {
super.tearDown();
}
}
@@ -0,0 +1,16 @@
public class JUnit3TestMethodIsPublicVoidNoArg extends junit.framework.TestCase {
public JUnit3TestMethodIsPublicVoidNoArg() {}
void <warning descr="Test method 'testOne()' is not declared 'public void'">testOne</warning>() {}
public int <warning descr="Test method 'testTwo()' is not declared 'public void'">testTwo</warning>() {
return 2;
}
public static void <warning descr="Test method 'testThree()' should not be 'static'">testThree</warning>() {}
public void <warning descr="Test method 'testFour()' should probably not have parameters">testFour</warning>(int i) {}
public void testFive() {}
}
@@ -0,0 +1,24 @@
import org.junit.Test;
public class JUnit4TestMethodIsPublicVoidNoArg {
@Test
JUnit4TestMethodIsPublicVoidNoArg() {}
@Test
void <warning descr="Test method 'testOne()' is not declared 'public void'">testOne</warning>() {}
@Test
public int <warning descr="Test method 'testTwo()' is not declared 'public void'">testTwo</warning>() {
return 2;
}
@Test
public static void <warning descr="Test method 'testThree()' should not be 'static'">testThree</warning>() {}
@Test
public void <warning descr="Test method 'testFour()' should probably not have parameters">testFour</warning>(int i) {}
@Test
public void testFive() {}
}
@@ -28,4 +28,6 @@ public class NativeMethodNamingConvention implements Runnable
public native void run();
private void a() {}
public static native void <warning descr="'native' method name 'b' is too short">b</warning>();
}
@@ -109,15 +109,20 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
lastWord = lastWord.substring(0, lastWord.length() - 10);
}
final int length = lastWord.length();
boolean upperCase = false;
for (int i = 0; i < length; i++) {
final char ch = lastWord.charAt(i);
if (Character.isUpperCase(ch)) {
if (i != 0) {
basePath.append('_');
if (!upperCase) {
upperCase = true;
if (i != 0) {
basePath.append('_');
}
}
basePath.append(Character.toLowerCase(ch));
}
else {
upperCase = false;
basePath.append(ch);
}
}
@@ -0,0 +1,57 @@
/*
* 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.junit;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class JUnit3StyleTestMethodInJUnit4ClassInspectionTest extends LightInspectionTestCase {
public void testJUnit3StyleTestMethodInJUnit4Class() { doTest(); }
public void testBeforeAnnotationUsed() { doTest(); }
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
return new JUnit3StyleTestMethodInJUnit4ClassInspection();
}
@Override
protected String[] getEnvironmentClasses() {
return new String[] {
"package org.junit;" +
"import java.lang.annotation.ElementType;" +
"import java.lang.annotation.Retention;" +
"import java.lang.annotation.RetentionPolicy;" +
"import java.lang.annotation.Target;" +
"@Retention(RetentionPolicy.RUNTIME)" +
"@Target({ElementType.METHOD})" +
"public @interface Before {}",
"package org.junit;" +
"import java.lang.annotation.ElementType;" +
"import java.lang.annotation.Retention;" +
"import java.lang.annotation.RetentionPolicy;" +
"import java.lang.annotation.Target;" +
"@Retention(RetentionPolicy.RUNTIME)" +
"@Target({ElementType.METHOD})" +
"public @interface Test {}"
};
}
}
@@ -0,0 +1,45 @@
/*
* 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.junit;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class TestCaseWithNoTestMethodsInspectionTest extends LightInspectionTestCase {
public void testTestCaseWithNoTestMethods() { doTest(); }
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
return new TestCaseWithNoTestMethodsInspection();
}
@Override
protected String[] getEnvironmentClasses() {
return new String[] {
"package junit.framework;" +
"public abstract class TestCase {" +
" protected void setUp() throws Exception {}" +
" protected void tearDown() throws Exception {}" +
"}"
};
}
}
@@ -0,0 +1,46 @@
/*
* 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.junit;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class TestMethodIsPublicVoidNoArgInspectionTest extends LightInspectionTestCase {
public void testJUnit3TestMethodIsPublicVoidNoArg() { doTest(); }
public void testJUnit4TestMethodIsPublicVoidNoArg() { doTest(); }
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
return new TestMethodIsPublicVoidNoArgInspection();
}
@Override
protected String[] getEnvironmentClasses() {
return new String[] {
"package org.junit; " +
"public @interface Test {\n" +
" java.lang.Class<? extends java.lang.Throwable> expected() default org.junit.Test.None.class;" +
"}",
"package junit.framework;" +
"public abstract class TestCase {}"};
}
}
@@ -23,6 +23,14 @@ import com.siyeh.ig.LightInspectionTestCase;
*/
public class InstanceMethodNamingConventionInspectionTest extends LightInspectionTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
final NativeMethodNamingConventionInspection inspection = new NativeMethodNamingConventionInspection();
inspection.m_minLength = 0;
myFixture.enableInspections(inspection);
}
@Override
protected InspectionProfileEntry getInspection() {
return new InstanceMethodNamingConventionInspection();
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.naming.com.siyeh.ig.naming;
package com.siyeh.ig.naming;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
@@ -23,6 +23,14 @@ import com.siyeh.ig.LightInspectionTestCase;
*/
public class StaticMethodNamingConventionInspectionTest extends LightInspectionTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
final NativeMethodNamingConventionInspection inspection = new NativeMethodNamingConventionInspection();
inspection.m_minLength = 0;
myFixture.enableInspections(inspection);
}
@Override
protected InspectionProfileEntry getInspection() {
return new StaticMethodNamingConventionInspection();