forked from phoedos/pmd
Compare commits
109 Commits
pmd_releas
...
pmd_releas
Author | SHA1 | Date | |
---|---|---|---|
|
f357da73b6 | ||
|
98e0c1f914 | ||
|
73fe285b1a | ||
|
3bf91a84d6 | ||
|
8b80efbd88 | ||
|
87db2a5736 | ||
|
4a395ee8b7 | ||
|
98278cfdfc | ||
|
145780de9c | ||
|
f3da33cca2 | ||
|
4cce31418a | ||
|
d8d8a9539f | ||
|
365e7a1f68 | ||
|
3fb43a060a | ||
|
819611dd23 | ||
|
0ffbe97a04 | ||
|
06d77b371a | ||
|
972eac40f0 | ||
|
336c06fb10 | ||
|
87803ed27a | ||
|
ca2794bf7d | ||
|
d921ffe1e3 | ||
|
0f48fd501d | ||
|
e1a41bdf98 | ||
|
ad1ffa5835 | ||
|
64012cc0b4 | ||
|
2500412b14 | ||
|
9f6190f3b6 | ||
|
9e620c2661 | ||
|
ac9fd51f84 | ||
|
93b4ce9bb4 | ||
|
f242c5c5f4 | ||
|
1984f5ac8a | ||
|
b553c52ef5 | ||
|
3abfc2fccb | ||
|
100dd09b28 | ||
|
a1ab0d6657 | ||
|
f0dd2b0519 | ||
|
58292bfc38 | ||
|
bd83821dd9 | ||
|
c0c79e522f | ||
|
0027fcdd77 | ||
|
abe800dfa9 | ||
|
203e39b9b3 | ||
|
922e35453a | ||
|
22671445e2 | ||
|
e3357987f2 | ||
|
dd8262cf69 | ||
|
89a3d5dd1e | ||
|
c5216fed79 | ||
|
d182626618 | ||
|
4ecb295b06 | ||
|
0785cef364 | ||
|
0671c2e478 | ||
|
1348ed8e06 | ||
|
c2ec86bac5 | ||
|
53a1f5280c | ||
|
9d8a2dd0a5 | ||
|
e93e9224ae | ||
|
df14ea9c95 | ||
|
617ca01a68 | ||
|
ee5885065e | ||
|
0b7cca49f1 | ||
|
8dc25abcfe | ||
|
2b92e22546 | ||
|
1b35a59997 | ||
|
39eb581134 | ||
|
d28e4f1fb5 | ||
|
66c1191984 | ||
|
42726428c5 | ||
|
19a13c0ab9 | ||
|
00ff9f25ae | ||
|
793af091c0 | ||
|
2c99fbd5e5 | ||
|
2aa1942015 | ||
|
c34b55285b | ||
|
b50e49777f | ||
|
a416513fc9 | ||
|
357f206102 | ||
|
cc43e6f8be | ||
|
3c316c2018 | ||
|
cae16d39d7 | ||
|
b5e7cbbaf3 | ||
|
7d630f6cb3 | ||
|
bc41b00206 | ||
|
171fdb877f | ||
|
12bbb65ebd | ||
|
3d73198ba9 | ||
|
e2a7356ccb | ||
|
a0d116ca6d | ||
|
857ae074e1 | ||
|
770fc5763e | ||
|
fba55905b6 | ||
|
a720b93431 | ||
|
de7a81202f | ||
|
f93a7bc67e | ||
|
b6c12fe449 | ||
|
fdb54ecc0e | ||
|
1910a6844c | ||
|
342e0c4789 | ||
|
a56f5545fa | ||
|
4d03c95158 | ||
|
d8961a903a | ||
|
f310138f9d | ||
|
e8c36b34f8 | ||
|
29a32bb2a7 | ||
|
fa9a4705e6 | ||
|
63f1814c80 | ||
|
c44a89cce3 |
21
.travis-settings.xml
Normal file
21
.travis-settings.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
|
||||
http://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<localRepository/>
|
||||
<interactiveMode/>
|
||||
<usePluginRegistry/>
|
||||
<offline/>
|
||||
<pluginGroups/>
|
||||
<servers>
|
||||
<server>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<username>${env.CI_DEPLOY_USERNAME}</username>
|
||||
<password>${env.CI_DEPLOY_PASSWORD}</password>
|
||||
</server>
|
||||
</servers>
|
||||
<mirrors/>
|
||||
<proxies/>
|
||||
<profiles/>
|
||||
<activeProfiles/>
|
||||
</settings>
|
22
.travis.yml
Normal file
22
.travis.yml
Normal file
@ -0,0 +1,22 @@
|
||||
language: java
|
||||
matrix:
|
||||
include:
|
||||
- jdk: oraclejdk7
|
||||
script:
|
||||
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && mvn test deploy --settings .travis-settings.xml'
|
||||
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] || mvn test'
|
||||
- jdk: oraclejdk8
|
||||
script: mvn test
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- adangel@users.sourceforge.net
|
||||
on_success: always
|
||||
on_failure: always
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.m2"
|
||||
env:
|
||||
global:
|
||||
- secure: KBEuB6U1p5RQXSYe157AwydFr/zpXQPA0IChVCgZV+X1mMyy9ZtrjH1J1AXuviseDDXDbaT25sRnsvpl82rfRw2xOkMGXHy4N95/ylTSr8DjHxTao71BhXsvFycNobFva5y2EGNWqDvpS8I2oSZo7Qk4la3yep3rcJQvcy6RDbbhpDTbL1QMFyadunIBm0WtqbunrMqtjSqaoPsXz8TiQuxHvX4vEXzVbaxV1QQt79Vi+daa6wAV3mRQAugnx+UffsC8JqMxgm06usWeJgCJzxgm8E7clZCLmf53B2TL8dK6bIYbqyvOY3uFxitsTG0d8Z0GOJwXBgZNgbniTRO8ZJSty5eZP8LBybbjVLSL25DNTWtCjADUL/uySnXIEidlMt2N/3QmH7zrGAfAk/tIwKpdRca2GLLydeXf6PSkiahnPEkIY/QupcsOLELhdifpdOjb8QW1OenA+vUbNM9dccLwKnX6Fj9cu4VQG601AcYDr2eyhq8WYkr3wYdw/6KdUa3hmplowTBs+qguppP+eOSgGuEsy38KLtqnvm6WlHy6tcLmcVYKG3DmR1b7TWXsOXC6/VMH8BHBkvsF1QdRg9+Cgx07vX3Hw7roPiYzmaO9Ajs20ATsUfRskMuWCTeTSK5pN8X27veRCZlhFjeKQMDdmfVwzpAfRgKsl3TEn1I=
|
||||
- secure: U1DfAv6acUUWe+dao/ZSDUX64JRadNJY16rITsdrM4ZNAJSuXpEY3p/LWcYjN7D49YmyutbXH9+L3KKQUQGrGXj9QTarfYvd8ZsKt4FK8yv7AFy+RQNIbAjNEHBzHx15p+srMheTaetl7aLwY0qhF+D/RtGapxHKyY4dBHrb0lp8VGyiCiL7Aop8GGskosi1mtirPBp/BStPZ2bEyxG0QzU5SsVWkJWwV9aWLPVAR/n7Xgx/6Gjl6Fed2c/WSrWi4vchm3Ny8pfTweOax3PGYYjBVxIfuX0mqmwuJsY7gNfXCfN3dPiPKGJPFy1pC+LGyGkklO5ReKFLd4O1ME6fU0dlIGfD6n+Q4H6/w9FHXegcKTfWIJm/MFa6vA/tJM5R6zJQuiTQJboHm/UmS/iQj76z0p6sK15Xp5vFId+/dHKqa8xY+Bt6HiXy6z401HOc8QcYBAf7TqhqUt/ZE7HN4be46uR90KmzIrWz6wEoDW7HfwQ9ZMbs55zoOXrvekyE9/gXskypO0p2JT3Y0vlvO27KQvIrSwI480kOVOrlyrYA+LZqlcKaayOuCuZh4lITQUYinUoZZict5joYthH+Cyh2zovoBpxsntDJdMnaZNLtSC7hlhpbMBYaT2y1O6vZH5Yix0mxuDvs/x6ogP5CNBeUYlXhaL+g4GnwKyr0ZA0=
|
@ -1,8 +1,8 @@
|
||||
[![PMD - Don't shoot the messenger][PMDLogo]][website]
|
||||
|
||||
PMD
|
||||
===
|
||||
|
||||
[![Build Status](https://travis-ci.org/pmd/pmd.svg?branch=master)](https://travis-ci.org/pmd/pmd)
|
||||
|
||||
About
|
||||
-----
|
||||
PMD is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks,
|
||||
@ -13,15 +13,12 @@ Java, C, C++, C#, PHP, Ruby, Fortran, JavaScript.
|
||||
Source
|
||||
------
|
||||
Our latest source of PMD can be found on [GitHub]. Fork us!
|
||||
The current status of this repo can be seen at [BuildHive].
|
||||
|
||||
News and Website
|
||||
----------------
|
||||
More information can be found on our [Website] and on [SourceForge].
|
||||
|
||||
|
||||
[PMDLogo]: http://pmd.sourceforge.net/pmd_logo.png
|
||||
[GitHub]: https://github.com/pmd/pmd
|
||||
[BuildHive]: https://buildhive.cloudbees.com/job/pmd/
|
||||
[Website]: http://pmd.sourceforge.net
|
||||
[Website]: https://pmd.github.io
|
||||
[SourceForge]: https://sourceforge.net/projects/pmd/
|
||||
|
316
do-release.sh
Executable file
316
do-release.sh
Executable file
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -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());
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
@ -127,7 +132,8 @@ public class DAAPathFinder {
|
||||
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);
|
||||
// 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);
|
||||
|
@ -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
|
||||
|
@ -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"/>
|
||||
|
@ -36,6 +36,20 @@ 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);
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -123,4 +123,4 @@ cygwin_paths
|
||||
|
||||
java_heapsize_settings
|
||||
|
||||
java ${HEAPSIZE} -cp "${classpath}" "${CLASSNAME}" ${@}
|
||||
java ${HEAPSIZE} -cp "${classpath}" "${CLASSNAME}" "$@"
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0</version>
|
||||
<version>5.3.5</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -31,6 +31,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableInitializer;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.lang.rule.properties.BooleanProperty;
|
||||
import net.sourceforge.pmd.lang.rule.properties.StringMultiProperty;
|
||||
|
||||
import org.jaxen.JaxenException;
|
||||
@ -63,9 +64,13 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
private static final StringMultiProperty TYPES_DESCRIPTOR = new StringMultiProperty("types", "Affected types",
|
||||
new String[] { "java.sql.Connection", "java.sql.Statement", "java.sql.ResultSet" }, 2.0f, ',');
|
||||
|
||||
private static final BooleanProperty USE_CLOSE_AS_DEFAULT_TARGET = new BooleanProperty("closeAsDefaultTarget",
|
||||
"Consider 'close' as a target by default", true, 3.0f);
|
||||
|
||||
public CloseResourceRule() {
|
||||
definePropertyDescriptor(CLOSE_TARGETS_DESCRIPTOR);
|
||||
definePropertyDescriptor(TYPES_DESCRIPTOR);
|
||||
definePropertyDescriptor(USE_CLOSE_AS_DEFAULT_TARGET);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,6 +78,9 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
if (closeTargets.isEmpty() && getProperty(CLOSE_TARGETS_DESCRIPTOR) != null) {
|
||||
closeTargets.addAll(Arrays.asList(getProperty(CLOSE_TARGETS_DESCRIPTOR)));
|
||||
}
|
||||
if (getProperty(USE_CLOSE_AS_DEFAULT_TARGET) && !closeTargets.contains("close")) {
|
||||
closeTargets.add("close");
|
||||
}
|
||||
if (types.isEmpty() && getProperty(TYPES_DESCRIPTOR) != null) {
|
||||
types.addAll(Arrays.asList(getProperty(TYPES_DESCRIPTOR)));
|
||||
}
|
||||
@ -121,14 +129,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 +160,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 +183,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 +211,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];
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user