Compare commits

..

94 Commits

Author SHA1 Message Date
Andreas Dangel
0ffbe97a04 [maven-release-plugin] prepare release pmd_releases/5.3.4 2015-09-18 12:36:06 +02:00
Andreas Dangel
06d77b371a Use release profile PMD_GPG_PROFILE 2015-09-18 12:24:27 +02:00
Andreas Dangel
972eac40f0 Specify gpg.keyname via -Darguments 2015-09-18 11:57:09 +02:00
Andreas Dangel
336c06fb10 Actually use the variables PMD_GPG_KEY and PMD_SF_USER 2015-09-18 11:49:20 +02:00
Andreas Dangel
87803ed27a Prepare pmd release 5.3.4 2015-09-18 11:44:40 +02:00
Andreas Dangel
ca2794bf7d Fixes for the release script 2015-09-18 11:40:16 +02:00
Andreas Dangel
d921ffe1e3 Add the release shell script 2015-09-18 11:25:30 +02:00
Andreas Dangel
0f48fd501d #1393 PMD hanging during DataflowAnomalyAnalysis 2015-09-18 10:17:01 +02:00
Andreas Dangel
e1a41bdf98 #1405 UnusedPrivateMethod false positive?
Don't use the auxclasspath if not provided.
2015-09-17 20:26:07 +02:00
Andreas Dangel
ad1ffa5835 #1404 Java8 'Unnecessary use of fully qualified name' in Streams Collector 2015-09-16 22:11:18 +02:00
Andreas Dangel
64012cc0b4 verified #1405 UnusedPrivateMethod false positive? 2015-09-16 21:37:17 +02:00
Andreas Dangel
2500412b14 #1403 False positive UnusedPrivateMethod with JAVA8 2015-09-14 22:36:05 +02:00
Andreas Dangel
9f6190f3b6 #1380 InsufficientStringBufferDeclaration false positive when literal string passed to a lookup service 2015-09-13 10:20:58 +02:00
Andreas Dangel
9e620c2661 #1388 ConstructorCallsOverridableMethodRule doesn't work with params? 2015-09-12 17:56:45 +02:00
Andreas Dangel
ac9fd51f84 #1392 SimplifyStartsWith false-negative 2015-09-11 12:22:49 +02:00
Andreas Dangel
93b4ce9bb4 #1394 dogfood.xml - Unable to exclude rules [UncommentedEmptyMethod] 2015-09-08 20:03:28 +02:00
Andreas Dangel
f242c5c5f4 Upgrade maven-pmd-plugin to 3.5 and add pmd execution
The profile "reports" was accidently deactivated by adding other
profiles. Now pmd and checkstyle are executed with all builds.
2015-09-08 19:58:21 +02:00
Andreas Dangel
1984f5ac8a #1395 UnusedPrivateMethod false positive for array element method call 2015-09-08 19:45:49 +02:00
Andreas Dangel
b553c52ef5 #1396 PrematureDeclaration lambda false positive 2015-09-07 20:23:10 +02:00
Andreas Dangel
3abfc2fccb #1397 StringToString should ignore method references 2015-09-07 20:01:18 +02:00
Andreas Dangel
100dd09b28 #1398 False positive for GuardLogStatementJavaUtil with Log4j 2015-09-06 11:06:48 +02:00
Andreas Dangel
a1ab0d6657 #1399 False positive for VariableNamingConventions with annotation @interface 2015-09-05 19:53:05 +02:00
Andreas Dangel
f0dd2b0519 #1400 False positive with JUnit4TestShouldUseBeforeAnnotation 2015-09-05 19:39:31 +02:00
Andreas Dangel
58292bfc38 #1401 False positive for StringBuilder.append called with constructor 2015-09-05 12:10:38 +02:00
Andreas Dangel
bd83821dd9 Fix unit test 2015-09-04 21:58:01 +02:00
Andreas Dangel
c0c79e522f #1371 fix unit test 2015-09-04 21:55:16 +02:00
Andreas Dangel
0027fcdd77 Update changelog 2015-09-04 21:55:08 +02:00
José Manuel Rolón
abe800dfa9 Fixed InsufficientStringBufferDeclaration error detection.
Summary:
Added new method to obtaint the lenght of strings added after a constructor.
Added new test for this case.

Fix: http://sourceforge.net/p/pmd/bugs/1371/

Test Plan: Run tests.

Reviewers: jmsotuyo

Reviewed By: jmsotuyo

Differential Revision: http://ph.monits.com/D12322
2015-09-04 21:53:45 +02:00
Andreas Dangel
203e39b9b3 Added a new if to check for the append statements after an append contructor.
Summary:
Now the rule check for appends after a contructor call.
Added a new test for this case.
Issue: http://sourceforge.net/p/pmd/bugs/1370/

Test Plan: Run tests.

Reviewers: jmsotuyo

Reviewed By: jmsotuyo

Differential Revision: http://ph.monits.com/D12292
2015-09-04 21:34:38 +02:00
Andreas Dangel
922e35453a #1402 Windows-Only: File exclusions are not case insensitive 2015-09-04 21:22:47 +02:00
Andreas Dangel
22671445e2 #1370 ConsecutiveAppendsShouldReuse not detected properly on StringBuffer
Extended unit test
2015-09-04 20:15:07 +02:00
Andreas Dangel
e3357987f2 Update changelog 2015-09-04 20:14:56 +02:00
José Manuel Rolón
dd8262cf69 Added new append validation.
Check for an append even when the block first child is a LocalVariableDeclaration.
Added new test to check the validation.

Issue: http://sourceforge.net/p/pmd/bugs/1370/
2015-09-04 20:14:09 +02:00
Andreas Dangel
89a3d5dd1e #1384 NullPointerException in ConsecutiveLiteralAppendsRule 2015-08-01 20:28:38 +02:00
Andreas Dangel
c5216fed79 Fix site build 2015-07-25 20:38:03 +02:00
Andreas Dangel
d182626618 Update release-process with github 2015-07-25 19:59:28 +02:00
Andreas Dangel
4ecb295b06 Fix version of pmd-java8 module 2015-07-25 19:59:07 +02:00
Andreas Dangel
0785cef364 Prepare next development version 2015-07-25 16:00:08 +02:00
Andreas Dangel
0671c2e478 [maven-release-plugin] prepare for next development iteration 2015-07-25 15:28:23 +02:00
Andreas Dangel
1348ed8e06 [maven-release-plugin] prepare release pmd_releases/5.3.3 2015-07-25 15:28:22 +02:00
Andreas Dangel
c2ec86bac5 Prepare pmd release 5.3.3 2015-07-25 15:16:54 +02:00
Andreas Dangel
53a1f5280c Create the site separately, so that javadoc aggreate can work 2015-07-25 15:10:19 +02:00
Andreas Dangel
9d8a2dd0a5 Use github page 2015-07-25 15:10:12 +02:00
Andreas Dangel
e93e9224ae #1381 CPD Cannot use CSV/VS Renderers because they don't support encoding property 2015-07-19 22:34:57 +02:00
Andreas Dangel
df14ea9c95 #1379 PMD CLI: Cannot specify multiple properties 2015-07-13 19:50:40 +02:00
Andreas Dangel
617ca01a68 #1369 ConsecutiveLiteralAppends not detected properly on StringBuffer 2015-06-29 20:28:53 +02:00
Andreas Dangel
ee5885065e reformat, whitespace 2015-06-29 19:58:48 +02:00
Andreas Dangel
0b7cca49f1 fix typo 2015-06-28 21:56:55 +02:00
Andreas Dangel
8dc25abcfe #1376 CompareObjectsWithEquals fails for type annotated method parameter 2015-06-28 21:51:04 +02:00
Andreas Dangel
2b92e22546 #1372 False Negative for CloseResource rule.
already fixed with #1375
2015-06-20 18:38:09 +02:00
Andreas Dangel
1b35a59997 #1375 CloseResource not detected properly 2015-06-20 18:15:02 +02:00
Juan Pablo Civile
39eb581134 Fix run.sh for paths with spaces
When redirecting arguments, "$@" must be used.

cherry-picked: 429e1a91a160c609c9b3bd4094ce2718b42793a1
cherry-picked: 59f5c8639277a572ae39128837e891ab1f178e0b
2015-06-06 19:38:02 +02:00
Andreas Dangel
d28e4f1fb5 #1366 UselessParentheses false positive on multiple equality operators 2015-06-01 20:06:01 +02:00
Andreas Dangel
66c1191984 #1365 Aggregated javadoc report is missing 2015-05-31 14:01:40 +02:00
Andreas Dangel
42726428c5 Fix links on the integrations page 2015-05-31 12:14:45 +02:00
Andreas Dangel
19a13c0ab9 #1364 FieldDeclarationsShouldBeAtStartOfClass false positive using multiple annotations 2015-05-31 10:29:42 +02:00
Andreas Dangel
00ff9f25ae Prepare next development version 2015-05-22 19:28:37 +02:00
Andreas Dangel
793af091c0 [maven-release-plugin] prepare for next development iteration 2015-05-22 18:23:42 +02:00
Andreas Dangel
2c99fbd5e5 [maven-release-plugin] prepare release pmd_releases/5.3.2 2015-05-22 18:23:41 +02:00
Andreas Dangel
2aa1942015 Prepare pmd release 5.3.2 2015-05-22 18:18:12 +02:00
Andreas Dangel
c34b55285b Adding back missing changelog entry for 5.3.1 2015-05-21 21:33:29 +02:00
Andreas Dangel
b50e49777f #1355 NullPointerException in a java file having a single comment line 2015-05-18 21:17:16 +02:00
Andreas Dangel
a416513fc9 reformat, whitespaces 2015-05-18 21:14:12 +02:00
Andreas Dangel
357f206102 #1330 AvoidReassigningParameters does not work with varargs 2015-05-15 20:24:06 +02:00
Andreas Dangel
cc43e6f8be #1354 Complex FieldDeclarationsShouldBeAtStartOfClass false positive with Spring annotations 2015-05-15 16:06:29 +02:00
Andreas Dangel
3c316c2018 #1343 MethodNamingConventions for overrided methods 2015-05-15 15:33:40 +02:00
Andreas Dangel
cae16d39d7 #1353 False positive "Only One Return" with lambda 2015-05-13 21:33:30 +02:00
Andreas Dangel
b5e7cbbaf3 verify #1349 VariableNamingConventions : underscore in final but at first position ? 2015-05-09 18:41:42 +02:00
Andreas Dangel
7d630f6cb3 verify #1347 False positive for GuardLogStatementJavaUtil 2015-05-09 18:37:02 +02:00
Andreas Dangel
bc41b00206 verify #1346 VariableNamingConventions do not work for method parameters 2015-05-09 18:31:48 +02:00
Andreas Dangel
171fdb877f #1345 UseCollectionIsEmpty throws NullPointerException 2015-05-09 18:25:12 +02:00
Andreas Dangel
12bbb65ebd Update fluido skin version to 1.4 2015-05-09 18:12:38 +02:00
Andreas Dangel
3d73198ba9 verify #1340 UseStringBufferForStringAppends False Positive with ternary operator 2015-05-01 18:41:21 +02:00
Andreas Dangel
e2a7356ccb verify #1341 pmd:GuardDebugLogging violates LOGGER.debug with format "{}"
It's a duplicate of #1224
2015-05-01 18:33:16 +02:00
Andreas Dangel
a0d116ca6d #1335 GuardLogStatementJavaUtil should not apply to SLF4J Logger 2015-05-01 18:27:18 +02:00
Andreas Dangel
857ae074e1 #1342 UseConcurrentHashMap false positive (with documentation example) 2015-04-30 20:07:54 +02:00
Andreas Dangel
770fc5763e Update project info reports, display modules after the main pages 2015-04-27 19:47:26 +02:00
Andreas Dangel
fba55905b6 Prepare next development version 2015-04-20 21:30:15 +02:00
Andreas Dangel
a720b93431 [maven-release-plugin] prepare for next development iteration 2015-04-20 20:15:12 +02:00
Andreas Dangel
de7a81202f [maven-release-plugin] prepare release pmd_releases/5.3.1 2015-04-20 20:15:11 +02:00
Andreas Dangel
f93a7bc67e Prepare pmd release 5.3.1 2015-04-20 19:55:55 +02:00
Andreas Dangel
b6c12fe449 Added deprecated old name for UseSingleton/UseUtilityClass
#1059 and #1339
2015-04-20 19:46:16 +02:00
Andreas Dangel
fdb54ecc0e #1337 False positive "Avoid throwing raw exception types" when exception is not thrown 2015-04-18 18:21:11 +02:00
Andreas Dangel
1910a6844c #1332 False Positive: UnusedPrivateMethod 2015-04-18 10:04:31 +02:00
Andreas Dangel
342e0c4789 Update changelog 2015-04-16 19:28:52 +02:00
Andreas Dangel
a56f5545fa Merge branch 'fix-null-pointer-exceptions' of https://github.com/Vampire/pmd into Vampire-fix-null-pointer-exceptions 2015-04-16 19:21:47 +02:00
Andreas Dangel
4d03c95158 #1338 The pmd-java8 POM bears the wrong parent module version 2015-04-14 19:50:32 +02:00
Björn Kautler
d8961a903a Fix NullPointerException in ClassScope.resolveGenericType() 2015-04-14 11:24:23 +02:00
Björn Kautler
f310138f9d Fix NullPointerException in ClassScope.qualifyTypeName() 2015-04-14 11:24:21 +02:00
Björn Kautler
e8c36b34f8 Make TypeSet resolvers null-safe 2015-04-14 11:24:20 +02:00
Andreas Dangel
29a32bb2a7 #1333 Error while processing Java file with Lambda expressions 2015-04-13 20:01:28 +02:00
Andreas Dangel
fa9a4705e6 Prepare next development version 2015-04-13 19:57:34 +02:00
Andreas Dangel
63f1814c80 Define the goals for releaseing explicitly 2015-04-04 12:39:18 +02:00
Andreas Dangel
c44a89cce3 [maven-release-plugin] prepare for next development iteration 2015-04-01 20:06:39 +02:00
96 changed files with 2319 additions and 674 deletions

316
do-release.sh Executable file

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.3.0</version>
<version>5.3.4</version>
</parent>
<properties>

View File

@ -228,25 +228,25 @@ public class PMDTaskImpl {
}
private void setupClassLoader() {
if (classpath == null) {
project.log("Using the normal ClassLoader", Project.MSG_VERBOSE);
} else {
project.log("Using the AntClassLoader", Project.MSG_VERBOSE);
// must be true, otherwise you'll get ClassCastExceptions as classes
// are loaded twice
// and exist in multiple class loaders
boolean parentFirst = true;
configuration.setClassLoader(new AntClassLoader(Thread.currentThread().getContextClassLoader(), project,
classpath, parentFirst));
classpath = new Path(project);
}
/*
* 'basedir' is added to the path to make sure that relative paths
* such as "<ruleset>resources/custom_ruleset.xml</ruleset>" still
* work when ant is invoked from a different directory using "-f"
*/
classpath.add(new Path(null, project.getBaseDir().toString()));
project.log("Using the AntClassLoader: " + classpath, Project.MSG_VERBOSE);
// must be true, otherwise you'll get ClassCastExceptions as classes
// are loaded twice
// and exist in multiple class loaders
boolean parentFirst = true;
configuration.setClassLoader(new AntClassLoader(Thread.currentThread().getContextClassLoader(), project,
classpath, parentFirst));
try {
/*
* 'basedir' is added to the path to make sure that relative paths
* such as "<ruleset>resources/custom_ruleset.xml</ruleset>" still
* work when ant is invoked from a different directory using "-f"
*/
configuration.prependClasspath(project.getBaseDir().toString());
if (auxClasspath != null) {
project.log("Using auxclasspath: " + auxClasspath, Project.MSG_VERBOSE);
configuration.prependClasspath(auxClasspath.toString());

View File

@ -4,6 +4,8 @@
package net.sourceforge.pmd.cli;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import net.sourceforge.pmd.PMDConfiguration;
@ -60,8 +62,9 @@ public class PMDParameters {
@Parameter(names = { "-minimumpriority", "-min" }, description = "Rule priority threshold; rules with lower priority than configured here won't be used. Default is '5' which is the lowest priority.", converter = RulePriorityConverter.class)
private RulePriority minimumPriority = RulePriority.LOW;
@Parameter(names = { "-property", "-P" }, description = "{name}={value}: Define a property for the report format.", converter = PropertyConverter.class)
private Properties properties = new Properties();
@Parameter(names = { "-property", "-P" }, description = "{name}={value}: Define a property for the report format.",
converter = PropertyConverter.class)
private List<Properties> properties = new ArrayList<Properties>();
@Parameter(names = { "-reportfile", "-r" }, description = "Sends report output to a file; default to System.out.")
private String reportfile = null;
@ -186,7 +189,11 @@ public class PMDParameters {
}
public Properties getProperties() {
return properties;
Properties result = new Properties();
for (Properties p : properties) {
result.putAll(p);
}
return result;
}
public String getReportfile() {

View File

@ -3,10 +3,12 @@
*/
package net.sourceforge.pmd.cpd;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FilenameFilter;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
@ -19,6 +21,7 @@ import java.util.Set;
import net.sourceforge.pmd.AbstractConfiguration;
import net.sourceforge.pmd.util.FileFinder;
import net.sourceforge.pmd.util.FileUtil;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.Parameter;
@ -173,12 +176,7 @@ public class CPDConfiguration extends AbstractConfiguration {
}
try {
Renderer renderer = clazz.getDeclaredConstructor().newInstance();
PropertyDescriptor encodingProperty = new PropertyDescriptor("encoding", clazz);
Method method = encodingProperty.getWriteMethod();
if (method != null) {
method.invoke(renderer, encoding);
}
setRendererEncoding(renderer, encoding);
return renderer;
} catch (Exception e) {
System.err.println("Couldn't instantiate renderer, defaulting to SimpleRenderer: " + e);
@ -186,6 +184,19 @@ public class CPDConfiguration extends AbstractConfiguration {
}
}
private static void setRendererEncoding(Renderer renderer, String encoding)
throws IllegalAccessException, InvocationTargetException {
try {
PropertyDescriptor encodingProperty = new PropertyDescriptor("encoding", renderer.getClass());
Method method = encodingProperty.getWriteMethod();
if (method != null) {
method.invoke(renderer, encoding);
}
} catch (IntrospectionException e) {
// ignored - maybe this renderer doesn't have a encoding property
}
}
public static String[] getRenderers() {
String[] result = RENDERERS.keySet().toArray(new String[RENDERERS.size()]);
Arrays.sort(result);
@ -275,10 +286,10 @@ public class CPDConfiguration extends AbstractConfiguration {
if (excludedFile.isDirectory()) {
List<File> files = finder.findFilesFrom(excludedFile, languageFilter, true);
for (File f : files) {
exclusions.add(f.getAbsolutePath());
exclusions.add(FileUtil.normalizeFilename(f.getAbsolutePath()));
}
} else {
exclusions.add(excludedFile.getAbsolutePath());
exclusions.add(FileUtil.normalizeFilename(excludedFile.getAbsolutePath()));
}
}
}
@ -286,7 +297,7 @@ public class CPDConfiguration extends AbstractConfiguration {
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
File f = new File(dir, name);
if (exclusions.contains(f.getAbsolutePath())) {
if (exclusions.contains(FileUtil.normalizeFilename(f.getAbsolutePath()))) {
System.err.println("Excluding " + f.getAbsolutePath());
return false;
}

View File

@ -17,6 +17,9 @@ public class Linker {
private final static Logger LOGGER = Logger.getLogger(Linker.class.getName());
private final static String CLASS_NAME = Linker.class.getCanonicalName();
/** Maximum loops to prevent hanging of PMD. See https://sourceforge.net/p/pmd/bugs/1393/ */
private static final int MAX_LOOPS = 100;
private final DataFlowHandler dataFlowHandler;
private List<StackObject> braceStack;
private List<StackObject> continueBreakReturnStack;
@ -37,7 +40,9 @@ public class Linker {
// the last index of the sequence.
LOGGER.fine("SequenceChecking continueBreakReturnStack elements");
SequenceChecker sc = new SequenceChecker(braceStack);
while (!sc.run()) {
int i = 0;
while (!sc.run() && i < MAX_LOOPS) {
i++;
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("After sc.run - starting Sequence checking loop with firstIndex=" + sc.getFirstIndex()
+ ", lastIndex " + sc.getLastIndex() + " with this StackList " + dump("braceStack", braceStack));

View File

@ -17,6 +17,9 @@ import net.sourceforge.pmd.lang.dfa.NodeType;
public class DAAPathFinder {
private static final int MAX_PATHS = 5000;
/** Maximum loops to prevent hanging of PMD. See https://sourceforge.net/p/pmd/bugs/1393/ */
private static final int MAX_LOOPS = 100;
private DataFlowNode rootNode;
private Executable shim;
private CurrentPath currentPath = new CurrentPath();
@ -59,7 +62,9 @@ public class DAAPathFinder {
* Builds up the path.
* */
private void phase2(boolean flag) {
while (!currentPath.isEndNode()) {
int i = 0;
while (!currentPath.isEndNode() && i < MAX_LOOPS) {
i++;
if (currentPath.isBranch() || currentPath.isFirstDoStatement()) {
if (flag) {
addNodeToTree();
@ -126,8 +131,9 @@ public class DAAPathFinder {
PathElement last = (PathElement) stack.getLastLeaf().getUserObject();
DataFlowNode inode = currentPath.getLast();
if (inode.getChildren().size() > last.currentChild) {
// for some unknown reasons last.currentChild might not be a children of inode, see bug 1597987
DataFlowNode child = inode.getChildren().get(last.currentChild);
// for some unknown reasons last.currentChild might not be a children of inode, see bug 1597987
// see https://sourceforge.net/p/pmd/bugs/606/
DataFlowNode child = inode.getChildren().get(last.currentChild);
this.currentPath.addLast(child);
}
} else {
@ -313,6 +319,7 @@ public class DAAPathFinder {
int counter = 0;
if (treeNode.getParent() != null) {
// for some unknown reasons the parent of treeNode might be null, see bug 1597987
// see https://sourceforge.net/p/pmd/bugs/606/
int childCount = treeNode.getParent().getChildCount();
for (int i = 0; i < childCount; i++) {
DefaultMutableTreeNode tNode = (DefaultMutableTreeNode) treeNode.getParent().getChildAt(i);

View File

@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
@ -46,6 +47,20 @@ public final class FileUtil {
return name;
}
/**
* Normalizes the filename by taking the casing into account, e.g. on Windows,
* the filename is changed to lowercase only.
* @param fileName the file name
* @return the normalized file name
*/
public static String normalizeFilename(String fileName) {
if (fileName != null && File.separatorChar == '\\') {
// windows
return fileName.toLowerCase(Locale.ROOT);
}
return fileName;
}
/**
* Collects a list of DataSources using a comma separated list of input file
* locations to process. If a file location is a directory, the directory

View File

@ -88,7 +88,7 @@
<exclude name="PositionLiteralsFirstInComparisons"/>
<exclude name="PreserveStackTrace"/>
<exclude name="UncommentedEmptyConstructor"/>
<exclude name="UncommentedEmptyMethod"/>
<exclude name="UncommentedEmptyMethodBody"/>
<exclude name="UnnecessaryLocalBeforeReturn"/>
<exclude name="AbstractClassWithoutAbstractMethod"/>
<exclude name="AccessorClassGeneration"/>

View File

@ -35,7 +35,21 @@ public class PMDCommandLineInterfaceTest {
Assert.assertEquals("output_folder", params.getProperties().getProperty("outputDir"));
}
@Test
public void testMultipleProperties() {
PMDParameters params = new PMDParameters();
String[] args = { "-d", "source_folder", "-f", "ideaj", "-P", "sourcePath=/home/user/source/",
"-P", "fileName=Foo.java",
"-P", "classAndMethodName=Foo.method",
"-R", "java-empty" };
PMDCommandLineInterface.extractParameters(params, args, "PMD");
Assert.assertEquals("/home/user/source/", params.getProperties().getProperty("sourcePath"));
Assert.assertEquals("Foo.java", params.getProperties().getProperty("fileName"));
Assert.assertEquals("Foo.method", params.getProperties().getProperty("classAndMethodName"));
}
@Test
public void testSetStatusCodeOrExit_DoExit() {
exit.expectSystemExitWithStatus(0);

View File

@ -0,0 +1,29 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.cpd;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;
public class CPDConfigurationTest {
@Test
public void testRenderers() {
Map<String, Class<? extends Renderer>> renderersToTest = new HashMap<String, Class<? extends Renderer>>();
renderersToTest.put("csv", CSVRenderer.class);
renderersToTest.put("xml", XMLRenderer.class);
renderersToTest.put("csv_with_linecount_per_file", CSVWithLinecountPerFileRenderer.class);
renderersToTest.put("vs", VSRenderer.class);
renderersToTest.put("text", SimpleRenderer.class);
for (Map.Entry<String, Class<? extends Renderer>> entry : renderersToTest.entrySet()) {
Renderer r = CPDConfiguration.getRendererFromString(entry.getKey(), "UTF-8");
Assert.assertNotNull(r);
Assert.assertSame(entry.getValue(), r.getClass());
}
}
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.3.0</version>
<version>5.3.4</version>
</parent>
<properties>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.3.0</version>
<version>5.3.4</version>
</parent>
<properties>

View File

@ -8,7 +8,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.3.0</version>
<version>5.3.4</version>
</parent>
<properties>

View File

@ -123,4 +123,4 @@ cygwin_paths
java_heapsize_settings
java ${HEAPSIZE} -cp "${classpath}" "${CLASSNAME}" ${@}
java ${HEAPSIZE} -cp "${classpath}" "${CLASSNAME}" "$@"

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.3.0</version>
<version>5.3.4</version>
</parent>
<properties>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.3.0</version>
<version>5.3.4</version>
</parent>
<properties>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>5.3.0</version>
<version>5.3.4</version>
</parent>
<properties>

View File

@ -47,8 +47,11 @@ public class ASTCompilationUnit extends AbstractJavaTypeNode implements RootNode
}
public ASTPackageDeclaration getPackageDeclaration() {
Node n = jjtGetChild(0);
return n instanceof ASTPackageDeclaration ? (ASTPackageDeclaration) n : null;
if (jjtGetNumChildren() > 0) {
Node n = jjtGetChild(0);
return n instanceof ASTPackageDeclaration ? (ASTPackageDeclaration) n : null;
}
return null;
}
public ClassTypeResolver getClassTypeResolver() {

View File

@ -104,14 +104,32 @@ public abstract class AbstractInefficientZeroCheck extends AbstractJavaRule {
private boolean isCompare(Node equality) {
if (isLiteralLeftHand(equality)) {
return checkComparison(inverse.get(equality.getImage()), equality, 0);
} else {
} else if (isLiteralRightHand(equality)) {
return checkComparison(equality.getImage(), equality, 1);
}
return false;
}
private boolean isLiteralLeftHand(Node equality) {
return equality.jjtGetChild(0).jjtGetChild(0).jjtGetNumChildren() > 0
&& equality.jjtGetChild(0).jjtGetChild(0).jjtGetChild(0) instanceof ASTLiteral;
return isLiteral(equality, 0);
}
private boolean isLiteralRightHand(Node equality) {
return isLiteral(equality, 1);
}
private boolean isLiteral(Node equality, int child) {
Node target = equality.jjtGetChild(child);
target = getFirstChildOrThis(target);
target = getFirstChildOrThis(target);
return target instanceof ASTLiteral;
}
private Node getFirstChildOrThis(Node node) {
if (node.jjtGetNumChildren() > 0) {
return node.jjtGetChild(0);
}
return node;
}
/**
@ -126,7 +144,10 @@ public abstract class AbstractInefficientZeroCheck extends AbstractJavaRule {
* @see #getComparisonTargets()
*/
private boolean checkComparison(String operator, Node equality, int i) {
Node target = equality.jjtGetChild(i).jjtGetChild(0).jjtGetChild(0);
Node target = equality
.jjtGetChild(i)
.jjtGetChild(0)
.jjtGetChild(0);
return target instanceof ASTLiteral && getComparisonTargets().get(operator).contains(target.getImage());
}

View File

@ -9,6 +9,7 @@ import java.util.List;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
@ -31,9 +32,11 @@ public class OnlyOneReturnRule extends AbstractJavaRule {
List<ASTReturnStatement> returnNodes = new ArrayList<ASTReturnStatement>();
node.findDescendantsOfType(ASTReturnStatement.class, returnNodes, false);
returnNodes = filterLambdaExpressions(returnNodes);
if (returnNodes.size() > 1) {
for (Iterator<ASTReturnStatement> i = returnNodes.iterator(); i.hasNext();) {
Node problem = i.next();
Node problem = i.next();
// skip the last one, it's OK
if (!i.hasNext()) {
continue;
@ -44,4 +47,21 @@ public class OnlyOneReturnRule extends AbstractJavaRule {
return data;
}
/**
* Checks whether the return statement is inside a lambda expression, and if
* so, this return statement is removed.
*
* @param returnNodes
* all the return statements inside the method
* @return all return statements, that are NOT within a lambda expression.
*/
private List<ASTReturnStatement> filterLambdaExpressions(List<ASTReturnStatement> returnNodes) {
List<ASTReturnStatement> filtered = new ArrayList<ASTReturnStatement>();
for (ASTReturnStatement ret : returnNodes) {
if (ret.getFirstParentOfType(ASTLambdaExpression.class) == null) {
filtered.add(ret);
}
}
return filtered;
}
}

View File

@ -32,6 +32,7 @@ public class AvoidReassigningParametersRule extends AbstractJavaRule {
if ((jocc.isOnLeftHandSide() || jocc.isSelfAssignment())
&& jocc.getNameForWhichThisIsAQualifier() == null
&& !jocc.useThisOrSuper()
&& !decl.isVarargs()
&& (!decl.isArray() || jocc.getLocation().jjtGetParent().jjtGetParent().jjtGetNumChildren() == 1)) {
// not an array or no primary suffix to access the array
// values

View File

@ -58,7 +58,7 @@ public class CloseResourceRule extends AbstractJavaRule {
private Set<String> closeTargets = new HashSet<String>();
private static final StringMultiProperty CLOSE_TARGETS_DESCRIPTOR = new StringMultiProperty("closeTargets",
"Methods which may close this resource", new String[] {}, 1.0f, ',');
"Methods which may close this resource", new String[] {"close"}, 1.0f, ',');
private static final StringMultiProperty TYPES_DESCRIPTOR = new StringMultiProperty("types", "Affected types",
new String[] { "java.sql.Connection", "java.sql.Statement", "java.sql.ResultSet" }, 2.0f, ',');
@ -121,14 +121,8 @@ public class CloseResourceRule extends AbstractJavaRule {
if (clazz.getType() != null && types.contains(clazz.getType().getName()) || clazz.getType() == null
&& simpleTypes.contains(toSimpleType(clazz.getImage())) || types.contains(clazz.getImage())) {
// if the variables are initialized with null, then they
// are ignored.
// At some point later in the code, there is an
// assignment - however, this is currently ignored
if (!hasNullInitializer(var)) {
ASTVariableDeclaratorId id = var.getFirstDescendantOfType(ASTVariableDeclaratorId.class);
ids.add(id);
}
ASTVariableDeclaratorId id = var.getFirstDescendantOfType(ASTVariableDeclaratorId.class);
ids.add(id);
}
}
}
@ -158,7 +152,6 @@ public class CloseResourceRule extends AbstractJavaRule {
// What are the chances of a Connection being instantiated in a
// for-loop init block? Anyway, I'm lazy!
String variableToClose = id.getImage();
String target = variableToClose + ".close";
Node n = var;
while (!(n instanceof ASTBlock) && !(n instanceof ASTConstructorDeclaration)) {
@ -182,7 +175,9 @@ public class CloseResourceRule extends AbstractJavaRule {
// variable declaration and
// the beginning of the try block.
ASTBlockStatement tryBlock = t.getFirstParentOfType(ASTBlockStatement.class);
if (parentBlock.jjtGetParent() == tryBlock.jjtGetParent()) {
if (!hasNullInitializer(var) // no need to check for critical statements, if
// the variable has been initialized with null
&& parentBlock.jjtGetParent() == tryBlock.jjtGetParent()) {
List<ASTBlockStatement> blocks = parentBlock.jjtGetParent().findChildrenOfType(ASTBlockStatement.class);
int parentBlockIndex = blocks.indexOf(parentBlock);
@ -208,11 +203,7 @@ public class CloseResourceRule extends AbstractJavaRule {
List<ASTName> names = f.findDescendantsOfType(ASTName.class);
for (ASTName oName : names) {
String name = oName.getImage();
if (name.equals(target) && nullCheckIfCondition(f, oName, variableToClose)) {
closed = true;
break;
}
if (name.contains(".")) {
if (name != null && name.contains(".")) {
String[] parts = name.split("\\.");
if (parts.length == 2) {
String methodName = parts[1];

View File

@ -78,11 +78,8 @@ public class CompareObjectsWithEqualsRule extends AbstractJavaRule {
}
if (nd0.isReferenceType() && nd1.isReferenceType()) {
ASTReferenceType type0 = (ASTReferenceType) ((Node) nd0.getAccessNodeParent()).jjtGetChild(0)
.jjtGetChild(0);
ASTReferenceType type1 = (ASTReferenceType) ((Node) nd1.getAccessNodeParent()).jjtGetChild(0)
.jjtGetChild(0);
ASTReferenceType type0 = ((Node) nd0.getAccessNodeParent()).getFirstDescendantOfType(ASTReferenceType.class);
ASTReferenceType type1 = ((Node) nd1.getAccessNodeParent()).getFirstDescendantOfType(ASTReferenceType.class);
// skip, if it is an enum
if (type0.getType() != null && type0.getType().equals(type1.getType()) && type0.getType().isEnum()) {
return data;

View File

@ -916,7 +916,7 @@ public final class ConstructorCallsOverridableMethodRule extends AbstractJavaRul
}
private static List<String> getMethodDeclaratorParameterTypes(Node methodOrConstructorDeclarator) {
List<ASTFormalParameter> parameters = methodOrConstructorDeclarator.findChildrenOfType(ASTFormalParameter.class);
List<ASTFormalParameter> parameters = methodOrConstructorDeclarator.findDescendantsOfType(ASTFormalParameter.class);
List<String> parameterTypes = new ArrayList<String>();
if (parameters != null) {
for (ASTFormalParameter p : parameters) {

View File

@ -4,6 +4,7 @@
package net.sourceforge.pmd.lang.java.rule.design;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
@ -50,7 +51,7 @@ public class FieldDeclarationsShouldBeAtStartOfClassRule extends AbstractJavaRul
for (int i = 0; i < parent.jjtGetNumChildren(); i++) {
Node child = parent.jjtGetChild(i);
if (child.jjtGetNumChildren() > 0) {
child = child.jjtGetChild(0);
child = skipAnnotations(child);
}
if (child.equals(node)) {
break;
@ -75,4 +76,21 @@ public class FieldDeclarationsShouldBeAtStartOfClassRule extends AbstractJavaRul
}
return data;
}
/**
* Ignore all annotations, until anything, that is not an annotation and
* return this node
* @param child the node from where to start the search
* @return the first child or the first child after annotations
*/
private Node skipAnnotations(Node child) {
Node nextChild = child.jjtGetChild(0);
for (int j = 0; j < child.jjtGetNumChildren(); j++) {
if (!(child.jjtGetChild(j) instanceof ASTAnnotation)) {
nextChild = child.jjtGetChild(j);
break;
}
}
return nextChild;
}
}

View File

@ -98,27 +98,16 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
if (importDeclaration.isStatic()) {
String[] importParts = importDeclaration.getImportedName().split("\\.");
String[] nameParts = name.split("\\.");
boolean checkClassImport = false;
if (importDeclaration.isImportOnDemand()) {
// Name class part matches class part of static import?
if (nameParts[nameParts.length - 2].equals(importParts[importParts.length - 1])) {
checkClassImport = true;
matches.add(importDeclaration);
}
} else {
// Last 2 parts match?
if (nameParts[nameParts.length - 1].equals(importParts[importParts.length - 1])
&& nameParts[nameParts.length - 2].equals(importParts[importParts.length - 2])) {
checkClassImport = true;
}
}
if (checkClassImport) {
// Name class part matches a direct class import?
String nameEnd = "." + nameParts[nameParts.length - 2];
for (ASTImportDeclaration importDeclaration2 : imports) {
if (!importDeclaration2.isStatic() && !importDeclaration2.isImportOnDemand()
&& importDeclaration2.getImportedName().endsWith(nameEnd)) {
matches.add(importDeclaration2);
}
matches.add(importDeclaration);
}
}
}
@ -126,8 +115,10 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
}
if (!matches.isEmpty()) {
String importStr = matches.get(0).getImportedName() + (matches.get(0).isImportOnDemand() ? ".*" : "");
addViolation(data, node, new Object[] { node.getImage(), importStr });
ASTImportDeclaration firstMatch = matches.get(0);
String importStr = firstMatch.getImportedName() + (matches.get(0).isImportOnDemand() ? ".*" : "");
String type = firstMatch.isStatic() ? "static " : "";
addViolation(data, node, new Object[] { node.getImage(), importStr, type });
}
matches.clear();

View File

@ -3,9 +3,11 @@
*/
package net.sourceforge.pmd.lang.java.rule.logging;
import java.util.List;
import java.util.logging.Level;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
public class GuardLogStatementJavaUtilRule extends GuardLogStatementRule {
@ -24,6 +26,10 @@ public class GuardLogStatementJavaUtilRule extends GuardLogStatementRule {
@Override
public Object visit(ASTCompilationUnit unit, Object data) {
if (isSlf4jOrLog4jImported(unit)) {
return data;
}
String[] logLevels = getProperty(LOG_LEVELS);
String[] guardMethods = getProperty(GUARD_METHODS);
@ -37,6 +43,16 @@ public class GuardLogStatementJavaUtilRule extends GuardLogStatementRule {
return super.visit(unit,data);
}
private boolean isSlf4jOrLog4jImported(ASTCompilationUnit unit) {
List<ASTImportDeclaration> imports = unit.findChildrenOfType(ASTImportDeclaration.class);
for (ASTImportDeclaration i : imports) {
if (i.getImportedName().startsWith("org.slf4j") || i.getImportedName().startsWith("org.apache.log4j")) {
return true;
}
}
return false;
}
private void configureGuards(String[] logLevels, String[] guardMethods) {
String[] methods = guardMethods;
if (methods.length != logLevels.length) {

View File

@ -3,9 +3,14 @@
*/
package net.sourceforge.pmd.lang.java.rule.naming;
import java.util.List;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTMarkerAnnotation;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
@ -30,6 +35,10 @@ public class MethodNamingConventionsRule extends AbstractJavaRule {
return data;
}
if (isOverriddenMethod(node)) {
return data;
}
String methodName = node.getImage();
if (Character.isUpperCase(methodName.charAt(0))) {
@ -41,4 +50,15 @@ public class MethodNamingConventionsRule extends AbstractJavaRule {
return data;
}
private boolean isOverriddenMethod(ASTMethodDeclarator node) {
ASTClassOrInterfaceBodyDeclaration declaration = node.getFirstParentOfType(ASTClassOrInterfaceBodyDeclaration.class);
List<ASTMarkerAnnotation> annotations = declaration.findDescendantsOfType(ASTMarkerAnnotation.class);
for (ASTMarkerAnnotation ann : annotations) {
ASTName name = ann.getFirstChildOfType(ASTName.class);
if (name != null && name.hasImageEqualTo("Override")) {
return true;
}
}
return false;
}
}

View File

@ -5,6 +5,7 @@ package net.sourceforge.pmd.lang.java.rule.naming;
import net.sourceforge.pmd.PropertyDescriptor;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
@ -111,9 +112,12 @@ public class VariableNamingConventionsRule extends AbstractJavaRule {
}
boolean isStatic = node.isStatic();
boolean isFinal = node.isFinal();
Node type = node.jjtGetParent().jjtGetParent().jjtGetParent();
// Anything from an interface is necessarily static and final
if (node.jjtGetParent().jjtGetParent().jjtGetParent() instanceof ASTClassOrInterfaceDeclaration
&& ((ASTClassOrInterfaceDeclaration) node.jjtGetParent().jjtGetParent().jjtGetParent()).isInterface()) {
// Anything inside an annotation type is also static and final
if (type instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) type).isInterface()
|| type instanceof ASTAnnotationTypeDeclaration) {
isStatic = true;
isFinal = true;
}

Some files were not shown because too many files have changed in this diff Show More