Compare commits
334
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
253d35a926 | ||
|
|
6007840346 | ||
|
|
dcb4ecc674 | ||
|
|
14cdf0b550 | ||
|
|
40ed778e43 | ||
|
|
3a46e9bab2 | ||
|
|
d7b8bae1c9 | ||
|
|
4ab1d0cbee | ||
|
|
8444b2fea6 | ||
|
|
a9d0de9450 | ||
|
|
08b7959557 | ||
|
|
495dcb5ea9 | ||
|
|
7339227e9c | ||
|
|
2cc91732ec | ||
|
|
4310b36344 | ||
|
|
575a5b6547 | ||
|
|
45dfd29a46 | ||
|
|
f8f0afb5b4 | ||
|
|
f8d1162886 | ||
|
|
020170bd76 | ||
|
|
5c80473108 | ||
|
|
9de0727e43 | ||
|
|
127a2be871 | ||
|
|
238f6b721b | ||
|
|
f4f2402661 | ||
|
|
c95051e97d | ||
|
|
7d5be34cd2 | ||
|
|
1e5c1c05ca | ||
|
|
5d11e77208 | ||
|
|
461365f543 | ||
|
|
8667aea076 | ||
|
|
b07c2f4409 | ||
|
|
db44bc4745 | ||
|
|
7421f28414 | ||
|
|
cf4938a65b | ||
|
|
5b6580448e | ||
|
|
229fc57073 | ||
|
|
65708ef704 | ||
|
|
d76b689c07 | ||
|
|
293731f009 | ||
|
|
88d1823c2e | ||
|
|
4adbeb04f1 | ||
|
|
648e697ab0 | ||
|
|
0660097db2 | ||
|
|
afc0f25795 | ||
|
|
c041f756c2 | ||
|
|
553cafff6e | ||
|
|
6efabd6909 | ||
|
|
f880d2ab95 | ||
|
|
63293f8b31 | ||
|
|
836af8d493 | ||
|
|
04f16d7627 | ||
|
|
ef0891d527 | ||
|
|
6afe513225 | ||
|
|
d1b9b3bc1f | ||
|
|
379b0de186 | ||
|
|
e71324e08c | ||
|
|
13f7675b67 | ||
|
|
1efdb72ba9 | ||
|
|
0d20fe7e1c | ||
|
|
58085e1520 | ||
|
|
f32beeb726 | ||
|
|
1816c1708a | ||
|
|
a8a18e6648 | ||
|
|
1b65c7fe91 | ||
|
|
44ee51d5a6 | ||
|
|
15fd444b7a | ||
|
|
147662e035 | ||
|
|
2afd30c283 | ||
|
|
d89549f994 | ||
|
|
8b8bb6d504 | ||
|
|
ef6bb6ed53 | ||
|
|
7d053d41c2 | ||
|
|
81378fe8ed | ||
|
|
ce8c4bf1a8 | ||
|
|
325fcaf5e4 | ||
|
|
361370db5d | ||
|
|
b9b0059797 | ||
|
|
baad0f2abe | ||
|
|
176cc2344d | ||
|
|
cb5ac3086e | ||
|
|
803d35005a | ||
|
|
6fc617bd11 | ||
|
|
6be8547f3e | ||
|
|
93227d1372 | ||
|
|
5f9114a02a | ||
|
|
494719d8ea | ||
|
|
3d84e3af74 | ||
|
|
cbde6f48ea | ||
|
|
c3f98356f8 | ||
|
|
ccd0badd4a | ||
|
|
2ce28f0ae3 | ||
|
|
c571abdb1d | ||
|
|
0725586b9a | ||
|
|
ccbb372a4f | ||
|
|
be51afc2b4 | ||
|
|
5f9e90761d | ||
|
|
4a0802a269 | ||
|
|
3de70426cf | ||
|
|
54ce3036b2 | ||
|
|
92678c0c0a | ||
|
|
1726c33c19 | ||
|
|
573186be69 | ||
|
|
090636e2db | ||
|
|
fc35a162d9 | ||
|
|
08fb59180d | ||
|
|
40bf82244f | ||
|
|
3c0516b86f | ||
|
|
32cc07d7cb | ||
|
|
1c08f94691 | ||
|
|
aab525196c | ||
|
|
518f1eff6d | ||
|
|
7915f08bc9 | ||
|
|
84cfa37b94 | ||
|
|
079ffeb4df | ||
|
|
6509f78448 | ||
|
|
89ffb56e4e | ||
|
|
dc7762b910 | ||
|
|
b9f8f2d4fb | ||
|
|
80c10534b3 | ||
|
|
e6f5380719 | ||
|
|
e4438ff8a2 | ||
|
|
44a8c0defe | ||
|
|
314ae4414b | ||
|
|
04527bc4cb | ||
|
|
82178809fa | ||
|
|
641ab25850 | ||
|
|
8c4d307ddd | ||
|
|
7a33d59a95 | ||
|
|
b9b6e13849 | ||
|
|
64441c8e93 | ||
|
|
d76c5b0de6 | ||
|
|
7bf00118a7 | ||
|
|
69dbbdfe2d | ||
|
|
699077fc7d | ||
|
|
e8e950ad20 | ||
|
|
607606534d | ||
|
|
207cf4842e | ||
|
|
03411d620e | ||
|
|
4a90118222 | ||
|
|
907a05670a | ||
|
|
eee4bf2550 | ||
|
|
a33e83addc | ||
|
|
e5a046007a | ||
|
|
e08ba3ea30 | ||
|
|
b2d5342493 | ||
|
|
f4a3e77185 | ||
|
|
d783bdcfb0 | ||
|
|
8bb07ad5f5 | ||
|
|
1dbf832d24 | ||
|
|
985ed57c52 | ||
|
|
f67dbb85f6 | ||
|
|
10db98bfee | ||
|
|
a735fb057e | ||
|
|
c099d50397 | ||
|
|
14510cdc5c | ||
|
|
fda6bef16e | ||
|
|
83eceab455 | ||
|
|
c141c91612 | ||
|
|
beb07e883f | ||
|
|
6a3e7ce6ec | ||
|
|
735b3e59f2 | ||
|
|
af57d270e4 | ||
|
|
2452db15f4 | ||
|
|
06cce6055a | ||
|
|
bc9379d9b4 | ||
|
|
9075c66a3a | ||
|
|
2a52757aa5 | ||
|
|
da50aa33ea | ||
|
|
b4c2a51781 | ||
|
|
07aa990ccc | ||
|
|
d621707e2f | ||
|
|
1c7d1a1f1d | ||
|
|
f2ec1be93f | ||
|
|
aab043787b | ||
|
|
90b1f65ea2 | ||
|
|
41b51c2158 | ||
|
|
f1a319d6ee | ||
|
|
c8a1307684 | ||
|
|
c9dca8dc92 | ||
|
|
0b1fc2b39f | ||
|
|
02c49ce881 | ||
|
|
b0a1223748 | ||
|
|
ba92715b19 | ||
|
|
2fa869a868 | ||
|
|
88634a220a | ||
|
|
3a7de73d96 | ||
|
|
7be198aaa3 | ||
|
|
aa87701ee5 | ||
|
|
933002de34 | ||
|
|
b753cc5ec5 | ||
|
|
b5706d0726 | ||
|
|
763bd9a478 | ||
|
|
7fe60c0747 | ||
|
|
3393507082 | ||
|
|
9da51952ef | ||
|
|
ce73691d5d | ||
|
|
808943e366 | ||
|
|
63afc1ec94 | ||
|
|
d788b6ce74 | ||
|
|
1e0b8cfa21 | ||
|
|
79853cdace | ||
|
|
2760827dc7 | ||
|
|
a7a84766bd | ||
|
|
6b60b4be34 | ||
|
|
1d190605e5 | ||
|
|
84c407f5d2 | ||
|
|
79e9b7616a | ||
|
|
af9f9d477d | ||
|
|
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 | ||
|
|
094c9c0ec9 | ||
|
|
8fd4528feb | ||
|
|
53055517d1 | ||
|
|
330708a35b | ||
|
|
ddb7c89505 | ||
|
|
4ad83be724 | ||
|
|
63017dbf08 | ||
|
|
79b92b71f1 | ||
|
|
e46bea857a | ||
|
|
65c2493ec7 | ||
|
|
12cc353d38 | ||
|
|
e57007e1be | ||
|
|
61e8412afe | ||
|
|
056b2fbaea | ||
|
|
45a0227f17 | ||
|
|
231a416c87 |
No files matched your search
@@ -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>
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
language: java
|
||||
before_script:
|
||||
- SHOULD_DEPLOY=no
|
||||
- '[ "${TRAVIS_SECURE_ENV_VARS}" = "true" ] && [ "${TRAVIS_PULL_REQUEST}" = "false" ] && SHOULD_DEPLOY=yes || ( [ "${SHOULD_DEPLOY}" != "yes" ] && echo "Skipping Deploy" )'
|
||||
- export SHOULD_DEPLOY
|
||||
matrix:
|
||||
include:
|
||||
- jdk: oraclejdk7
|
||||
script:
|
||||
- '[ "${SHOULD_DEPLOY}" = "yes" ] && mvn test deploy --settings .travis-settings.xml || ( [ "${SHOULD_DEPLOY}" != "yes" ] && echo "Skipping Deploy" )'
|
||||
- '[ "${SHOULD_DEPLOY}" = "yes" ] || mvn test'
|
||||
- jdk: oraclejdk8
|
||||
script: mvn test
|
||||
branches:
|
||||
except:
|
||||
- /^pmd_releases\/\d/
|
||||
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,27 +1,49 @@
|
||||
[![PMD - Don't shoot the messenger][PMDLogo]][website]
|
||||
# PMD
|
||||
|
||||
PMD
|
||||
===
|
||||
[](https://travis-ci.org/pmd/pmd)
|
||||
|
||||
## About
|
||||
|
||||
About
|
||||
-----
|
||||
PMD is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks,
|
||||
unnecessary object creation, and so forth. It supports Java, JavaScript, XML, XSL.
|
||||
Additionally it includes CPD, the copy-paste-detector. CPD finds duplicated code in
|
||||
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].
|
||||
## Source
|
||||
|
||||
Our latest source of PMD can be found on [GitHub]. Fork us!
|
||||
|
||||
### How to build PMD?
|
||||
|
||||
You'll need to have a `~/.m2/toolchains.xml` file setup with jdk 1.6 (for pmd 5.3.x), jdk 1.7 (for pmd 5.4.x and pmd 5.5.x)
|
||||
and jdk 1.8 (for some features in pmd 5.5.x). See [maven toolchains](https://maven.apache.org/guides/mini/guide-using-toolchains.html).
|
||||
A example file can be found here: [example-toolchains.xml](https://github.com/pmd/pmd/blob/master/example-toolchains.xml).
|
||||
|
||||
Use maven in the top-level directory:
|
||||
|
||||
mvn clean package
|
||||
|
||||
This will create the zip files in the directory `pmd-dist/target`:
|
||||
|
||||
cd pmd-dist/target
|
||||
ls *.zip
|
||||
|
||||
That's all !
|
||||
|
||||
### Bug Reports
|
||||
|
||||
We are using Sourceforge for bug tracking. Please file your bugs at <https://sourceforge.net/p/pmd/bugs/>.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
Pull requests are always welcome: <https://github.com/pmd/pmd/pulls>
|
||||
|
||||
|
||||
## News and Website
|
||||
|
||||
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/
|
||||
Executable
+308
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF8"?>
|
||||
<toolchains>
|
||||
<!-- place this file in ${user.home}/.m2/toolchains.xml -->
|
||||
|
||||
<toolchain>
|
||||
<type>jdk</type>
|
||||
<provides>
|
||||
<version>1.6</version>
|
||||
</provides>
|
||||
<configuration>
|
||||
<jdkHome>/path/to/jdk/1.6</jdkHome>
|
||||
</configuration>
|
||||
</toolchain>
|
||||
<toolchain>
|
||||
<type>jdk</type>
|
||||
<provides>
|
||||
<version>1.7</version>
|
||||
</provides>
|
||||
<configuration>
|
||||
<jdkHome>/path/to/jdk/1.7</jdkHome>
|
||||
</configuration>
|
||||
</toolchain>
|
||||
<toolchain>
|
||||
<type>jdk</type>
|
||||
<provides>
|
||||
<version>1.8</version>
|
||||
</provides>
|
||||
<configuration>
|
||||
<jdkHome>/path/to/jdk/1.8</jdkHome>
|
||||
</configuration>
|
||||
</toolchain>
|
||||
</toolchains>
|
||||
@@ -12,7 +12,7 @@
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd-build</artifactId>
|
||||
<name>PMD Build Plugin</name>
|
||||
<version>0.9</version>
|
||||
<version>0.10-SNAPSHOT</version>
|
||||
<packaging>maven-plugin</packaging>
|
||||
<description>
|
||||
<![CDATA[
|
||||
@@ -42,7 +42,7 @@ only if you modify the java code.
|
||||
<connection>scm:git:git://github.com/pmd/pmd.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/pmd/pmd.git</developerConnection>
|
||||
<url>https://github.com/pmd/pmd</url>
|
||||
<tag>pmd-build/0.9</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<developers>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
How to build PMD ?
|
||||
==================
|
||||
|
||||
Simply use maven: $ mvn compile
|
||||
|
||||
PMD now uses a small plugin to generate its website, so if you want to build the
|
||||
website ($ mvn site), you'll need to install it:
|
||||
|
||||
$ cd ../maven-plugin-pmd-build
|
||||
$ mvn clean install
|
||||
|
||||
That's all !
|
||||
|
||||
How to quickly build a "release" (zipfiles - for testing purpose only) ?
|
||||
------------------------------------------------------------------------
|
||||
|
||||
$ mvn -Dmaven.test.skip=true -Dmaven.clover.skip=true verify post-site
|
||||
|
||||
Full release process is documented in src/site/xdocs/pmd-release-process.xml
|
||||
+7
-1
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>net.sourceforge.pmd</groupId>
|
||||
<artifactId>pmd</artifactId>
|
||||
<version>5.3.0-SNAPSHOT</version>
|
||||
<version>5.3.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -93,6 +93,12 @@
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.saxon</groupId>
|
||||
|
||||
@@ -22,16 +22,25 @@ import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import net.sourceforge.pmd.benchmark.Benchmark;
|
||||
import net.sourceforge.pmd.benchmark.Benchmarker;
|
||||
import net.sourceforge.pmd.benchmark.TextReport;
|
||||
import net.sourceforge.pmd.cli.PMDCommandLineInterface;
|
||||
import net.sourceforge.pmd.cli.PMDParameters;
|
||||
import net.sourceforge.pmd.lang.*;
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageFilenameFilter;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.lang.LanguageVersionDiscoverer;
|
||||
import net.sourceforge.pmd.lang.LanguageVersionHandler;
|
||||
import net.sourceforge.pmd.lang.Parser;
|
||||
import net.sourceforge.pmd.lang.ParserOptions;
|
||||
import net.sourceforge.pmd.processor.MonoThreadProcessor;
|
||||
import net.sourceforge.pmd.processor.MultiThreadProcessor;
|
||||
import net.sourceforge.pmd.renderers.Renderer;
|
||||
import net.sourceforge.pmd.stat.Metric;
|
||||
import net.sourceforge.pmd.util.ClasspathClassLoader;
|
||||
import net.sourceforge.pmd.util.FileUtil;
|
||||
import net.sourceforge.pmd.util.IOUtil;
|
||||
import net.sourceforge.pmd.util.SystemUtils;
|
||||
@@ -353,6 +362,10 @@ public class PMD {
|
||||
} else {
|
||||
new MonoThreadProcessor(configuration).processFiles(ruleSetFactory, files, ctx, renderers);
|
||||
}
|
||||
|
||||
if (configuration.getClassLoader() instanceof ClasspathClassLoader) {
|
||||
IOUtil.tryCloseClassLoader(configuration.getClassLoader());
|
||||
}
|
||||
}
|
||||
|
||||
private static void sortFiles(final PMDConfiguration configuration, final List<DataSource> files) {
|
||||
@@ -380,6 +393,13 @@ public class PMD {
|
||||
*/
|
||||
public static List<DataSource> getApplicableFiles(PMDConfiguration configuration, Set<Language> languages) {
|
||||
long startFiles = System.nanoTime();
|
||||
List<DataSource> files = internalGetApplicableFiles(configuration, languages);
|
||||
long endFiles = System.nanoTime();
|
||||
Benchmarker.mark(Benchmark.CollectFiles, endFiles - startFiles, 0);
|
||||
return files;
|
||||
}
|
||||
|
||||
private static List<DataSource> internalGetApplicableFiles(PMDConfiguration configuration, Set<Language> languages) {
|
||||
LanguageFilenameFilter fileSelector = new LanguageFilenameFilter(languages);
|
||||
List<DataSource> files = new ArrayList<DataSource>();
|
||||
|
||||
@@ -398,8 +418,6 @@ public class PMD {
|
||||
throw new RuntimeException("Problem with DBURI: " + uriString, ex);
|
||||
}
|
||||
}
|
||||
long endFiles = System.nanoTime();
|
||||
Benchmarker.mark(Benchmark.CollectFiles, endFiles - startFiles, 0);
|
||||
return files;
|
||||
}
|
||||
|
||||
@@ -495,6 +513,8 @@ public class PMD {
|
||||
pmdVersion = properties.getProperty("version");
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.FINE, "Couldn't determine version of PMD", e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
}
|
||||
if (pmdVersion == null) {
|
||||
|
||||
@@ -54,6 +54,8 @@ import net.sourceforge.pmd.util.IOUtil;
|
||||
* <li>A comma separated list of input paths to process for source files.
|
||||
* This may include files, directories, archives (e.g. ZIP files), etc.
|
||||
* {@link #getInputPaths()}</li>
|
||||
* <li>A flag which controls, whether {@link RuleSetFactoryCompatibility} filter
|
||||
* should be used or not: #isRuleSetFactoryCompatibilityEnabled;
|
||||
* </ul>
|
||||
* <p>
|
||||
* <ul>
|
||||
@@ -94,6 +96,7 @@ public class PMDConfiguration extends AbstractConfiguration {
|
||||
private RulePriority minimumPriority = RulePriority.LOW;
|
||||
private String inputPaths;
|
||||
private String inputUri;
|
||||
private boolean ruleSetFactoryCompatibilityEnabled = true;
|
||||
|
||||
// Reporting options
|
||||
private String reportFormat;
|
||||
@@ -493,4 +496,27 @@ public class PMDConfiguration extends AbstractConfiguration {
|
||||
public void setBenchmark(boolean benchmark) {
|
||||
this.benchmark = benchmark;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the rule set factory compatibility feature is enabled.
|
||||
*
|
||||
* @return true, if the rule set factory compatibility feature is enabled
|
||||
*
|
||||
* @see RuleSetFactoryCompatibility
|
||||
*/
|
||||
public boolean isRuleSetFactoryCompatibilityEnabled() {
|
||||
return ruleSetFactoryCompatibilityEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rule set factory compatibility feature enabled/disabled.
|
||||
*
|
||||
* @param ruleSetFactoryCompatibilityEnabled <code>true</code> if the feature should be enabled
|
||||
*
|
||||
* @see RuleSetFactoryCompatibility
|
||||
*/
|
||||
public void setRuleSetFactoryCompatibilityEnabled(boolean ruleSetFactoryCompatibilityEnabled) {
|
||||
this.ruleSetFactoryCompatibilityEnabled = ruleSetFactoryCompatibilityEnabled;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,12 @@ import net.sourceforge.pmd.lang.rule.properties.StringProperty;
|
||||
|
||||
/**
|
||||
* This is the basic Rule interface for PMD rules.
|
||||
*
|
||||
* <p><strong>Thread safety:</strong>
|
||||
* PMD will create one instance of a rule per thread. The instances are
|
||||
* not shared across different threads. However, a single rule instance is
|
||||
* reused for analyzing multiple files.
|
||||
* </p>
|
||||
*/
|
||||
// FUTURE Implement Cloneable and clone()
|
||||
public interface Rule extends PropertySource {
|
||||
|
||||
@@ -309,17 +309,15 @@ public class RuleSet {
|
||||
Benchmarker.mark(Benchmark.Rule, rule.getName(), end - start, 1);
|
||||
start = end;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof ThreadDeath) {
|
||||
throw (ThreadDeath)t;
|
||||
} else if (ctx.isIgnoreExceptions()) {
|
||||
} catch (RuntimeException e) {
|
||||
if (ctx.isIgnoreExceptions()) {
|
||||
if (LOG.isLoggable(Level.WARNING)) {
|
||||
LOG.log(Level.WARNING, "Exception applying rule " + rule.getName()
|
||||
+ " on file " + ctx.getSourceCodeFilename() + ", continuing with next rule",
|
||||
t);
|
||||
e);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(t);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
package net.sourceforge.pmd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* Provides a simple filter mechanism to avoid failing to parse an old ruleset, which references rules, that
|
||||
* have either been removed from PMD already or renamed or moved to another ruleset.
|
||||
*
|
||||
* @see <a href="https://sourceforge.net/p/pmd/bugs/1360/">issue 1360</a>
|
||||
*/
|
||||
public class RuleSetFactoryCompatibility {
|
||||
private static final Logger LOG = Logger.getLogger(RuleSetFactoryCompatibility.class.getName());
|
||||
|
||||
private List<RuleSetFilter> filters = new LinkedList<RuleSetFilter>();
|
||||
|
||||
/**
|
||||
* Creates a new instance of the compatibility filter with the built-in filters for the
|
||||
* modified PMD rules.
|
||||
*/
|
||||
public RuleSetFactoryCompatibility() {
|
||||
// PMD 5.3.0
|
||||
addFilterRuleRenamed("java", "design", "UncommentedEmptyMethod", "UncommentedEmptyMethodBody");
|
||||
addFilterRuleRemoved("java", "controversial", "BooleanInversion");
|
||||
|
||||
// PMD 5.3.1
|
||||
addFilterRuleRenamed("java", "design", "UseSingleton", "UseUtilityClass");
|
||||
|
||||
// PMD 5.4.0
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyCatchBlock");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyIfStatement");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyWhileStmt");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyTryBlock");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyFinallyBlock");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptySwitchStatements");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptySynchronizedBlock");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyStatementNotInLoop");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyInitializer");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyStatementBlock");
|
||||
addFilterRuleMoved("java", "basic", "empty", "EmptyStaticInitializer");
|
||||
addFilterRuleMoved("java", "basic", "unnecessary", "UnnecessaryConversionTemporary");
|
||||
addFilterRuleMoved("java", "basic", "unnecessary", "UnnecessaryReturn");
|
||||
addFilterRuleMoved("java", "basic", "unnecessary", "UnnecessaryFinalModifier");
|
||||
addFilterRuleMoved("java", "basic", "unnecessary", "UselessOverridingMethod");
|
||||
addFilterRuleMoved("java", "basic", "unnecessary", "UselessOperationOnImmutable");
|
||||
addFilterRuleMoved("java", "basic", "unnecessary", "UnusedNullCheckInEquals");
|
||||
addFilterRuleMoved("java", "basic", "unnecessary", "UselessParentheses");
|
||||
}
|
||||
|
||||
void addFilterRuleRenamed(String language, String ruleset, String oldName, String newName) {
|
||||
filters.add(RuleSetFilter.ruleRenamed(language, ruleset, oldName, newName));
|
||||
}
|
||||
void addFilterRuleMoved(String language, String oldRuleset, String newRuleset, String ruleName) {
|
||||
filters.add(RuleSetFilter.ruleMoved(language, oldRuleset, newRuleset, ruleName));
|
||||
}
|
||||
void addFilterRuleRemoved(String language, String ruleset, String name) {
|
||||
filters.add(RuleSetFilter.ruleRemoved(language, ruleset, name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies all configured filters against the given input stream.
|
||||
* The resulting reader will contain the original ruleset modified by
|
||||
* the filters.
|
||||
*
|
||||
* @param stream
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public Reader filterRuleSetFile(InputStream stream) throws IOException {
|
||||
byte[] bytes = IOUtils.toByteArray(stream);
|
||||
String encoding = determineEncoding(bytes);
|
||||
String ruleset = new String(bytes, encoding);
|
||||
|
||||
ruleset = applyAllFilters(ruleset);
|
||||
|
||||
return new StringReader(ruleset);
|
||||
}
|
||||
|
||||
private String applyAllFilters(String in) {
|
||||
String result = in;
|
||||
for (RuleSetFilter filter : filters) {
|
||||
result = filter.apply(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final Pattern ENCODING_PATTERN = Pattern.compile("encoding=\"([^\"]+)\"");
|
||||
/**
|
||||
* Determines the encoding of the given bytes, assuming this is a XML document, which specifies
|
||||
* the encoding in the first 1024 bytes.
|
||||
*
|
||||
* @param bytes the input bytes, might be more or less than 1024 bytes
|
||||
* @return the determined encoding, falls back to the default UTF-8 encoding
|
||||
*/
|
||||
String determineEncoding(byte[] bytes) {
|
||||
String firstBytes = new String(bytes, 0, bytes.length > 1024 ? 1024 : bytes.length, Charset.forName("ISO-8859-1"));
|
||||
Matcher matcher = ENCODING_PATTERN.matcher(firstBytes);
|
||||
String encoding = Charset.forName("UTF-8").name();
|
||||
if (matcher.find()) {
|
||||
encoding = matcher.group(1);
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
|
||||
private static class RuleSetFilter {
|
||||
private final Pattern refPattern;
|
||||
private final String replacement;
|
||||
private Pattern exclusionPattern;
|
||||
private String exclusionReplacement;
|
||||
private final String logMessage;
|
||||
private RuleSetFilter(String refPattern, String replacement, String logMessage) {
|
||||
this.logMessage = logMessage;
|
||||
if (replacement != null) {
|
||||
this.refPattern = Pattern.compile("ref=\"" + Pattern.quote(refPattern) + "\"");
|
||||
this.replacement = "ref=\"" + replacement + "\"";
|
||||
} else {
|
||||
this.refPattern = Pattern.compile("<rule\\s+ref=\"" + Pattern.quote(refPattern) + "\"\\s*/>");
|
||||
this.replacement = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void setExclusionPattern(String oldName, String newName) {
|
||||
exclusionPattern = Pattern.compile("<exclude\\s+name=[\"']" + Pattern.quote(oldName) + "[\"']\\s*/>");
|
||||
if (newName != null) {
|
||||
exclusionReplacement = "<exclude name=\"" + newName + "\" />";
|
||||
} else {
|
||||
exclusionReplacement = "";
|
||||
}
|
||||
}
|
||||
|
||||
public static RuleSetFilter ruleRenamed(String language, String ruleset, String oldName, String newName) {
|
||||
String base = "rulesets/" + language + "/" + ruleset + ".xml/";
|
||||
RuleSetFilter filter = new RuleSetFilter(base + oldName, base + newName,
|
||||
"The rule \"" + oldName + "\" has been renamed to \"" + newName + "\". Please change your ruleset!");
|
||||
filter.setExclusionPattern(oldName, newName);
|
||||
return filter;
|
||||
}
|
||||
public static RuleSetFilter ruleMoved(String language, String oldRuleset, String newRuleset, String ruleName) {
|
||||
String base = "rulesets/" + language + "/";
|
||||
return new RuleSetFilter(base + oldRuleset + ".xml/" + ruleName, base + newRuleset + ".xml/" + ruleName,
|
||||
"The rule \"" + ruleName + "\" has been moved from ruleset \"" + oldRuleset + "\" to \"" + newRuleset + "\". Please change your ruleset!");
|
||||
}
|
||||
public static RuleSetFilter ruleRemoved(String language, String ruleset, String name) {
|
||||
RuleSetFilter filter = new RuleSetFilter("rulesets/" + language + "/" + ruleset + ".xml/" + name, null,
|
||||
"The rule \"" + name + "\" in ruleset \"" + ruleset + "\" has been removed from PMD and no longer exists. Please change your ruleset!");
|
||||
filter.setExclusionPattern(name, null);
|
||||
return filter;
|
||||
}
|
||||
|
||||
String apply(String in) {
|
||||
String result = in;
|
||||
Matcher matcher = refPattern.matcher(in);
|
||||
|
||||
if (matcher.find()) {
|
||||
result = matcher.replaceAll(replacement);
|
||||
|
||||
if (LOG.isLoggable(Level.WARNING)) {
|
||||
LOG.warning("Applying rule set filter: " + logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (exclusionPattern == null) return result;
|
||||
|
||||
Matcher exclusions = exclusionPattern.matcher(result);
|
||||
if (exclusions.find()) {
|
||||
result = exclusions.replaceAll(exclusionReplacement);
|
||||
|
||||
if (LOG.isLoggable(Level.WARNING)) {
|
||||
LOG.warning("Applying rule set filter for exclusions: " + logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,9 @@ public final class RulesetsFactoryUtils {
|
||||
public static RuleSetFactory getRulesetFactory(PMDConfiguration configuration) {
|
||||
RuleSetFactory ruleSetFactory = new RuleSetFactory();
|
||||
ruleSetFactory.setMinimumPriority(configuration.getMinimumPriority());
|
||||
if (!configuration.isRuleSetFactoryCompatibilityEnabled()) {
|
||||
ruleSetFactory.disableCompatibilityFilter();
|
||||
}
|
||||
return ruleSetFactory;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ public class PMDTask extends Task {
|
||||
private boolean shortFilenames;
|
||||
private String suppressMarker;
|
||||
private String rulesetFiles;
|
||||
private boolean noRuleSetCompatibility;
|
||||
private String encoding;
|
||||
private int threads;
|
||||
private int minimumPriority;
|
||||
@@ -236,4 +237,11 @@ public class PMDTask extends Task {
|
||||
return nestedRules;
|
||||
}
|
||||
|
||||
public boolean isNoRuleSetCompatibility() {
|
||||
return noRuleSetCompatibility;
|
||||
}
|
||||
|
||||
public void setNoRuleSetCompatibility(boolean noRuleSetCompatibility) {
|
||||
this.noRuleSetCompatibility = noRuleSetCompatibility;
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,14 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.tools.ant.AntClassLoader;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.DirectoryScanner;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.types.FileSet;
|
||||
import org.apache.tools.ant.types.Path;
|
||||
|
||||
import net.sourceforge.pmd.PMD;
|
||||
import net.sourceforge.pmd.PMDConfiguration;
|
||||
import net.sourceforge.pmd.Report;
|
||||
@@ -31,20 +39,13 @@ import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
import net.sourceforge.pmd.renderers.AbstractRenderer;
|
||||
import net.sourceforge.pmd.renderers.Renderer;
|
||||
import net.sourceforge.pmd.util.IOUtil;
|
||||
import net.sourceforge.pmd.util.StringUtil;
|
||||
import net.sourceforge.pmd.util.datasource.DataSource;
|
||||
import net.sourceforge.pmd.util.datasource.FileDataSource;
|
||||
import net.sourceforge.pmd.util.log.AntLogHandler;
|
||||
import net.sourceforge.pmd.util.log.ScopedLogHandlersManager;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.tools.ant.AntClassLoader;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.DirectoryScanner;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.types.FileSet;
|
||||
import org.apache.tools.ant.types.Path;
|
||||
|
||||
public class PMDTaskImpl {
|
||||
|
||||
private Path classpath;
|
||||
@@ -68,6 +69,7 @@ public class PMDTaskImpl {
|
||||
this.failOnRuleViolation = true;
|
||||
}
|
||||
configuration.setRuleSets(task.getRulesetFiles());
|
||||
configuration.setRuleSetFactoryCompatibilityEnabled(!task.isNoRuleSetCompatibility());
|
||||
if (task.getEncoding() != null) {
|
||||
configuration.setSourceEncoding(task.getEncoding());
|
||||
}
|
||||
@@ -100,6 +102,9 @@ public class PMDTaskImpl {
|
||||
// Setup RuleSetFactory and validate RuleSets
|
||||
RuleSetFactory ruleSetFactory = new RuleSetFactory();
|
||||
ruleSetFactory.setClassLoader(configuration.getClassLoader());
|
||||
if (!configuration.isRuleSetFactoryCompatibilityEnabled()) {
|
||||
ruleSetFactory.disableCompatibilityFilter();
|
||||
}
|
||||
try {
|
||||
// This is just used to validate and display rules. Each thread will
|
||||
// create its own ruleset
|
||||
@@ -228,25 +233,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());
|
||||
@@ -263,6 +268,7 @@ public class PMDTaskImpl {
|
||||
doTask();
|
||||
} finally {
|
||||
logManager.close();
|
||||
IOUtil.tryCloseClassLoader(configuration.getClassLoader());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,11 +130,12 @@ public class Benchmarker {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
for (DataSource dataSource: dataSources) {
|
||||
parser.parse(
|
||||
dataSource.getNiceFileName(false, null),
|
||||
new InputStreamReader(dataSource.getInputStream()
|
||||
)
|
||||
);
|
||||
InputStreamReader reader = new InputStreamReader(dataSource.getInputStream());
|
||||
try {
|
||||
parser.parse(dataSource.getNiceFileName(false, null), reader);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
@@ -169,13 +170,15 @@ public class Benchmarker {
|
||||
|
||||
RuleContext ctx = new RuleContext();
|
||||
long start = System.currentTimeMillis();
|
||||
Reader reader = null;
|
||||
for (DataSource dataSource: dataSources) {
|
||||
reader = new InputStreamReader(dataSource.getInputStream());
|
||||
ctx.setSourceCodeFilename(dataSource.getNiceFileName(false, null));
|
||||
new SourceCodeProcessor(config).processSourceCode(reader, ruleSets, ctx);
|
||||
IOUtils.closeQuietly(reader);
|
||||
}
|
||||
Reader reader = new InputStreamReader(dataSource.getInputStream());
|
||||
try {
|
||||
ctx.setSourceCodeFilename(dataSource.getNiceFileName(false, null));
|
||||
new SourceCodeProcessor(config).processSourceCode(reader, ruleSets, ctx);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
long elapsed = end - start;
|
||||
results.add(new RuleDuration(elapsed, rule));
|
||||
|
||||
@@ -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;
|
||||
@@ -75,13 +78,15 @@ public class PMDParameters {
|
||||
@Parameter(names = "-auxclasspath", description = "Specifies the classpath for libraries used by the source code. This is used by the type resolution. Alternatively, a 'file://' URL to a text file containing path elements on consecutive lines can be specified.")
|
||||
private String auxclasspath;
|
||||
|
||||
@Parameter(names = "-norulesetcompatibility", description = "Disable the ruleset compatibility filter. The filter is active by default and tries automatically 'fix' old ruleset files with old rule names")
|
||||
private boolean noRuleSetCompatibility = false;
|
||||
|
||||
// this has to be a public static class, so that JCommander can use it!
|
||||
public static class PropertyConverter implements IStringConverter<Properties> {
|
||||
|
||||
private static final char SEPARATOR = '=';
|
||||
|
||||
public Properties convert(String value) {
|
||||
Properties properties = new Properties();
|
||||
int indexOfSeparator = value.indexOf(SEPARATOR);
|
||||
if (indexOfSeparator < 0) {
|
||||
throw new ParameterException(
|
||||
@@ -89,6 +94,7 @@ public class PMDParameters {
|
||||
}
|
||||
String propertyName = value.substring(0, indexOfSeparator);
|
||||
String propertyValue = value.substring(indexOfSeparator + 1);
|
||||
Properties properties = new Properties();
|
||||
properties.put(propertyName, propertyValue);
|
||||
return properties;
|
||||
}
|
||||
@@ -127,6 +133,7 @@ public class PMDParameters {
|
||||
configuration.setReportProperties(params.getProperties());
|
||||
configuration.setReportShortNames(params.isShortnames());
|
||||
configuration.setRuleSets(params.getRulesets());
|
||||
configuration.setRuleSetFactoryCompatibilityEnabled(!params.noRuleSetCompatibility);
|
||||
configuration.setShowSuppressedViolations(params.isShowsuppressed());
|
||||
configuration.setSourceEncoding(params.getEncoding());
|
||||
configuration.setStressTest(params.isStress());
|
||||
@@ -186,7 +193,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() {
|
||||
|
||||
@@ -12,44 +12,50 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class AbstractTokenizer implements Tokenizer {
|
||||
|
||||
//FIXME depending on subclasses to assign local vars is rather fragile - better to make private and setup via explicit hook methods
|
||||
|
||||
protected List<String> stringToken; // List<String>, should be set by sub classes
|
||||
protected List<String> ignorableCharacter; // List<String>, should be set by sub classes
|
||||
// FIXME:Maybe an array of 'char' would be better for performance ?
|
||||
protected List<String> ignorableStmt; // List<String>, should be set by sub classes
|
||||
protected char oneLineCommentChar = '#'; // Most script languages ( shell, ruby, python,...) use this symbol for comment line
|
||||
// FIXME depending on subclasses to assign local vars is rather fragile -
|
||||
// better to make private and setup via explicit hook methods
|
||||
|
||||
private List<String> code;
|
||||
private int lineNumber = 0;
|
||||
private String currentLine;
|
||||
protected List<String> stringToken; // List<String>, should be set by sub
|
||||
// classes
|
||||
protected List<String> ignorableCharacter; // List<String>, should be set by
|
||||
// sub classes
|
||||
// FIXME:Maybe an array of 'char'
|
||||
// would be better for
|
||||
// performance ?
|
||||
protected List<String> ignorableStmt; // List<String>, should be set by sub
|
||||
// classes
|
||||
protected char oneLineCommentChar = '#'; // Most script languages ( shell,
|
||||
// ruby, python,...) use this
|
||||
// symbol for comment line
|
||||
|
||||
protected boolean spanMultipleLinesString = true; // Most languages do, so default is true
|
||||
protected Character spanMultipleLinesLineContinuationCharacter = null;
|
||||
private List<String> code;
|
||||
private int lineNumber = 0;
|
||||
private String currentLine;
|
||||
|
||||
private boolean downcaseString = true;
|
||||
protected boolean spanMultipleLinesString = true; // Most languages do, so
|
||||
// default is true
|
||||
protected Character spanMultipleLinesLineContinuationCharacter = null;
|
||||
|
||||
private boolean downcaseString = true;
|
||||
|
||||
public void tokenize(SourceCode tokens, Tokens tokenEntries) {
|
||||
code = tokens.getCode();
|
||||
|
||||
for ( lineNumber = 0; lineNumber < code.size(); lineNumber++ ) {
|
||||
currentLine = code.get(lineNumber);
|
||||
for (lineNumber = 0; lineNumber < code.size(); lineNumber++) {
|
||||
currentLine = code.get(lineNumber);
|
||||
int loc = 0;
|
||||
while ( loc < currentLine.length() ) {
|
||||
while (loc < currentLine.length()) {
|
||||
StringBuilder token = new StringBuilder();
|
||||
loc = getTokenFromLine(token,loc);
|
||||
loc = getTokenFromLine(token, loc);
|
||||
if (token.length() > 0 && !isIgnorableString(token.toString())) {
|
||||
if (downcaseString) {
|
||||
token = new StringBuilder(token.toString().toLowerCase());
|
||||
}
|
||||
// need to re-think how to link this
|
||||
// if ( CPD.debugEnable ) {
|
||||
// System.out.println("Token added:" + token.toString());
|
||||
// }
|
||||
tokenEntries.add(new TokenEntry(token.toString(),
|
||||
tokens.getFileName(),
|
||||
lineNumber)
|
||||
);
|
||||
// need to re-think how to link this
|
||||
// if ( CPD.debugEnable ) {
|
||||
// System.out.println("Token added:" + token.toString());
|
||||
// }
|
||||
tokenEntries.add(new TokenEntry(token.toString(), tokens.getFileName(), lineNumber));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -69,7 +75,8 @@ public abstract class AbstractTokenizer implements Tokenizer {
|
||||
}
|
||||
} else if (isString(tok)) {
|
||||
if (token.length() > 0) {
|
||||
return j; // we need to now parse the string as a separate token.
|
||||
return j; // we need to now parse the string as a
|
||||
// separate token.
|
||||
} else {
|
||||
// we are at the start of a string
|
||||
return parseString(token, j, tok);
|
||||
@@ -91,66 +98,67 @@ public abstract class AbstractTokenizer implements Tokenizer {
|
||||
boolean escaped = false;
|
||||
boolean done = false;
|
||||
char tok = ' '; // this will be replaced.
|
||||
while ((loc < currentLine.length()) && ! done) {
|
||||
while (loc < currentLine.length() && !done) {
|
||||
tok = currentLine.charAt(loc);
|
||||
if (escaped && tok == stringDelimiter) { // Found an escaped string
|
||||
escaped = false;
|
||||
} else if (tok == stringDelimiter && (token.length() > 0)) { // We are done, we found the end of the string...
|
||||
} else if (tok == stringDelimiter && token.length() > 0) {
|
||||
// We are done, we found the end of the string...
|
||||
done = true;
|
||||
} else if (tok == '\\') { // Found an escaped char
|
||||
escaped = true;
|
||||
} else { // Adding char...
|
||||
} else { // Adding char...
|
||||
escaped = false;
|
||||
}
|
||||
//Adding char to String:" + token.toString());
|
||||
// Adding char to String:" + token.toString());
|
||||
token.append(tok);
|
||||
loc++;
|
||||
}
|
||||
// Handling multiple lines string
|
||||
if ( ! done && // ... we didn't find the end of the string
|
||||
loc >= currentLine.length() && // ... we have reach the end of the line ( the String is incomplete, for the moment at least)
|
||||
spanMultipleLinesString && // ... the language allow multiple line span Strings
|
||||
lineNumber < code.size() - 1 // ... there is still more lines to parse
|
||||
) {
|
||||
// removes last character, if it is the line continuation (e.g. backslash) character
|
||||
if (!done && // ... we didn't find the end of the string
|
||||
loc >= currentLine.length() && // ... we have reach the end of
|
||||
// the line ( the String is
|
||||
// incomplete, for the moment at
|
||||
// least)
|
||||
spanMultipleLinesString && // ... the language allow multiple
|
||||
// line span Strings
|
||||
lineNumber < code.size() - 1 // ... there is still more lines to
|
||||
// parse
|
||||
) {
|
||||
// removes last character, if it is the line continuation (e.g.
|
||||
// backslash) character
|
||||
if (spanMultipleLinesLineContinuationCharacter != null && token.length() > 0
|
||||
&& token.charAt(token.length() - 1) == spanMultipleLinesLineContinuationCharacter.charValue()) {
|
||||
token.deleteCharAt(token.length() - 1);
|
||||
}
|
||||
// parsing new line
|
||||
currentLine = code.get(++lineNumber);
|
||||
// Warning : recursive call !
|
||||
loc = parseString(token, 0, stringDelimiter);
|
||||
// parsing new line
|
||||
currentLine = code.get(++lineNumber);
|
||||
// Warning : recursive call !
|
||||
loc = parseString(token, 0, stringDelimiter);
|
||||
}
|
||||
return loc + 1;
|
||||
}
|
||||
|
||||
private boolean ignoreCharacter(char tok)
|
||||
{
|
||||
return ignorableCharacter.contains(String.valueOf(tok));
|
||||
private boolean ignoreCharacter(char tok) {
|
||||
return ignorableCharacter.contains(String.valueOf(tok));
|
||||
}
|
||||
|
||||
private boolean isString(char tok)
|
||||
{
|
||||
return stringToken.contains(String.valueOf(tok));
|
||||
private boolean isString(char tok) {
|
||||
return stringToken.contains(String.valueOf(tok));
|
||||
}
|
||||
|
||||
private boolean isComment(char tok)
|
||||
{
|
||||
private boolean isComment(char tok) {
|
||||
return tok == oneLineCommentChar;
|
||||
}
|
||||
|
||||
private int getCommentToken(StringBuilder token, int loc)
|
||||
{
|
||||
while (loc < currentLine.length())
|
||||
{
|
||||
private int getCommentToken(StringBuilder token, int loc) {
|
||||
while (loc < currentLine.length()) {
|
||||
token.append(currentLine.charAt(loc++));
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
private boolean isIgnorableString(String token)
|
||||
{
|
||||
return ignorableStmt.contains(token);
|
||||
private boolean isIgnorableString(String token) {
|
||||
return ignorableStmt.contains(token);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ package net.sourceforge.pmd.cpd;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
@@ -77,7 +76,7 @@ public class CPDCommandLineInterface {
|
||||
//Add files
|
||||
if ( null != arguments.getFiles() && ! arguments.getFiles().isEmpty() )
|
||||
{
|
||||
addSourcesFilesToCPD(arguments.getFiles(), arguments.filenameFilter(), cpd, !arguments.isNonRecursive());
|
||||
addSourcesFilesToCPD(arguments.getFiles(), cpd, !arguments.isNonRecursive());
|
||||
}
|
||||
|
||||
//Add Database URIS
|
||||
@@ -87,13 +86,13 @@ public class CPDCommandLineInterface {
|
||||
}
|
||||
|
||||
cpd.go();
|
||||
System.out.println(arguments.getRenderer().render(cpd.getMatches()));
|
||||
if (cpd.getMatches().hasNext()) {
|
||||
System.out.println(arguments.getRenderer().render(cpd.getMatches()));
|
||||
setStatusCodeOrExit(DUPLICATE_CODE_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addSourcesFilesToCPD(List<File> files, FilenameFilter filter, CPD cpd, boolean recursive) {
|
||||
private static void addSourcesFilesToCPD(List<File> files, CPD cpd, boolean recursive) {
|
||||
try {
|
||||
for (File file : files) {
|
||||
if (!file.exists()) {
|
||||
@@ -105,13 +104,7 @@ public class CPDCommandLineInterface {
|
||||
cpd.addAllInDirectory(file);
|
||||
}
|
||||
} else {
|
||||
//Add a single file if it is accepted by the file filter
|
||||
File directory = file.getAbsoluteFile().getParentFile();
|
||||
String filename = file.getName();
|
||||
|
||||
if (filter.accept(directory, filename)) {
|
||||
cpd.add(file);
|
||||
}
|
||||
cpd.add(file);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -47,6 +47,7 @@ public class CPDTask extends Task {
|
||||
private boolean ignoreLiterals;
|
||||
private boolean ignoreIdentifiers;
|
||||
private boolean ignoreAnnotations;
|
||||
private boolean ignoreUsings;
|
||||
private boolean skipLexicalErrors;
|
||||
private boolean skipDuplicateFiles;
|
||||
private boolean skipBlocks = true;
|
||||
@@ -104,6 +105,9 @@ public class CPDTask extends Task {
|
||||
if (ignoreAnnotations) {
|
||||
p.setProperty(Tokenizer.IGNORE_ANNOTATIONS, "true");
|
||||
}
|
||||
if (ignoreUsings) {
|
||||
p.setProperty(Tokenizer.IGNORE_USINGS, "true");
|
||||
}
|
||||
p.setProperty(Tokenizer.OPTION_SKIP_BLOCKS, Boolean.toString(skipBlocks));
|
||||
p.setProperty(Tokenizer.OPTION_SKIP_BLOCKS_PATTERN, skipBlocksPattern);
|
||||
return LanguageFactory.createLanguage(language, p);
|
||||
@@ -188,6 +192,10 @@ public class CPDTask extends Task {
|
||||
this.ignoreAnnotations = value;
|
||||
}
|
||||
|
||||
public void setIgnoreUsings(boolean value) {
|
||||
this.ignoreUsings = value;
|
||||
}
|
||||
|
||||
public void setSkipLexicalErrors(boolean skipLexicalErrors) {
|
||||
this.skipLexicalErrors = skipLexicalErrors;
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ public class GUI implements CPDListener {
|
||||
public boolean canIgnoreIdentifiers() { return false; }
|
||||
public boolean canIgnoreLiterals() { return false; }
|
||||
public boolean canIgnoreAnnotations() { return false; }
|
||||
public boolean canIgnoreUsings() { return false; }
|
||||
public abstract String[] extensions();
|
||||
}
|
||||
|
||||
@@ -121,6 +122,10 @@ public class GUI implements CPDListener {
|
||||
public boolean canIgnoreLiterals() {
|
||||
return "java".equals(terseName);
|
||||
}
|
||||
@Override
|
||||
public boolean canIgnoreUsings() {
|
||||
return "cs".equals(terseName);
|
||||
}
|
||||
};
|
||||
}
|
||||
LANGUAGE_SETS[index][0] = "by extension...";
|
||||
@@ -277,6 +282,7 @@ public class GUI implements CPDListener {
|
||||
private JCheckBox ignoreIdentifiersCheckbox = new JCheckBox("", false);
|
||||
private JCheckBox ignoreLiteralsCheckbox = new JCheckBox("", false);
|
||||
private JCheckBox ignoreAnnotationsCheckbox = new JCheckBox("", false);
|
||||
private JCheckBox ignoreUsingsCheckbox = new JCheckBox("", false);
|
||||
private JComboBox languageBox = new JComboBox();
|
||||
private JTextField extensionField = new JTextField();
|
||||
private JLabel extensionLabel = new JLabel("Extension:", SwingConstants.RIGHT);
|
||||
@@ -362,6 +368,7 @@ public class GUI implements CPDListener {
|
||||
ignoreIdentifiersCheckbox.setEnabled(current.canIgnoreIdentifiers());
|
||||
ignoreLiteralsCheckbox.setEnabled(current.canIgnoreLiterals());
|
||||
ignoreAnnotationsCheckbox.setEnabled(current.canIgnoreAnnotations());
|
||||
ignoreUsingsCheckbox.setEnabled(current.canIgnoreUsings());
|
||||
extensionField.setText(current.extensions()[0]);
|
||||
boolean enableExtension = current.extensions()[0].length() == 0;
|
||||
extensionField.setEnabled(enableExtension);
|
||||
@@ -414,6 +421,13 @@ public class GUI implements CPDListener {
|
||||
helper.nextRow();
|
||||
helper.addLabel("Ignore annotations?");
|
||||
helper.add(ignoreAnnotationsCheckbox);
|
||||
helper.addLabel("");
|
||||
helper.addLabel("");
|
||||
helper.nextRow();
|
||||
|
||||
helper.nextRow();
|
||||
helper.addLabel("Ignore usings?");
|
||||
helper.add(ignoreUsingsCheckbox);
|
||||
helper.add(goButton);
|
||||
helper.add(cxButton);
|
||||
helper.nextRow();
|
||||
@@ -590,6 +604,7 @@ public class GUI implements CPDListener {
|
||||
config.setIgnoreIdentifiers(ignoreIdentifiersCheckbox.isSelected());
|
||||
config.setIgnoreLiterals(ignoreLiteralsCheckbox.isSelected());
|
||||
config.setIgnoreAnnotations(ignoreAnnotationsCheckbox.isSelected());
|
||||
config.setIgnoreUsings(ignoreUsingsCheckbox.isSelected());
|
||||
p.setProperty(LanguageFactory.EXTENSION, extensionField.getText());
|
||||
|
||||
LanguageConfig conf = languageConfigFor((String)languageBox.getSelectedItem());
|
||||
|
||||
@@ -15,158 +15,167 @@ import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.PMD;
|
||||
|
||||
import org.apache.commons.io.ByteOrderMark;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.BOMInputStream;
|
||||
|
||||
public class SourceCode {
|
||||
|
||||
public static abstract class CodeLoader {
|
||||
private SoftReference<List<String>> code;
|
||||
private SoftReference<List<String>> code;
|
||||
|
||||
public List<String> getCode() {
|
||||
List<String> c = null;
|
||||
if (code != null) {
|
||||
c = code.get();
|
||||
}
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
this.code = new SoftReference<List<String>>(load());
|
||||
return code.get();
|
||||
}
|
||||
public List<String> getCode() {
|
||||
List<String> c = null;
|
||||
if (code != null) {
|
||||
c = code.get();
|
||||
}
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
this.code = new SoftReference<List<String>>(load());
|
||||
return code.get();
|
||||
}
|
||||
|
||||
public abstract String getFileName();
|
||||
public abstract String getFileName();
|
||||
|
||||
protected abstract Reader getReader() throws Exception;
|
||||
protected abstract Reader getReader() throws Exception;
|
||||
|
||||
protected List<String> load() {
|
||||
LineNumberReader lnr = null;
|
||||
try {
|
||||
lnr = new LineNumberReader(getReader());
|
||||
List<String> lines = new ArrayList<String>();
|
||||
String currentLine;
|
||||
while ((currentLine = lnr.readLine()) != null) {
|
||||
lines.add(currentLine);
|
||||
}
|
||||
return lines;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(lnr);
|
||||
}
|
||||
}
|
||||
protected List<String> load() {
|
||||
LineNumberReader lnr = null;
|
||||
try {
|
||||
lnr = new LineNumberReader(getReader());
|
||||
List<String> lines = new ArrayList<String>();
|
||||
String currentLine;
|
||||
while ((currentLine = lnr.readLine()) != null) {
|
||||
lines.add(currentLine);
|
||||
}
|
||||
return lines;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(lnr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FileCodeLoader extends CodeLoader {
|
||||
private File file;
|
||||
private String encoding;
|
||||
private File file;
|
||||
private String encoding;
|
||||
|
||||
public FileCodeLoader(File file, String encoding) {
|
||||
this.file = file;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
public FileCodeLoader(File file, String encoding) {
|
||||
this.file = file;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getReader() throws Exception {
|
||||
return new InputStreamReader(new FileInputStream(file), encoding);
|
||||
}
|
||||
@Override
|
||||
public Reader getReader() throws Exception {
|
||||
BOMInputStream inputStream =
|
||||
new BOMInputStream(new FileInputStream(file),
|
||||
ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE, ByteOrderMark.UTF_16LE);
|
||||
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
if (inputStream.hasBOM()) {
|
||||
encoding = inputStream.getBOMCharsetName();
|
||||
}
|
||||
return new InputStreamReader(inputStream, encoding);
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringCodeLoader extends CodeLoader {
|
||||
public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
|
||||
public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
|
||||
|
||||
private String code;
|
||||
private String code;
|
||||
|
||||
private String name;
|
||||
private String name;
|
||||
|
||||
public StringCodeLoader(String code) {
|
||||
this(code, DEFAULT_NAME);
|
||||
}
|
||||
public StringCodeLoader(String code) {
|
||||
this(code, DEFAULT_NAME);
|
||||
}
|
||||
|
||||
public StringCodeLoader(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
public StringCodeLoader(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getReader() {
|
||||
return new StringReader(code);
|
||||
}
|
||||
@Override
|
||||
public Reader getReader() {
|
||||
return new StringReader(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class ReaderCodeLoader extends CodeLoader {
|
||||
public static final String DEFAULT_NAME = "CODE_LOADED_FROM_READER";
|
||||
public static final String DEFAULT_NAME = "CODE_LOADED_FROM_READER";
|
||||
|
||||
private Reader code;
|
||||
private Reader code;
|
||||
|
||||
private String name;
|
||||
private String name;
|
||||
|
||||
public ReaderCodeLoader(Reader code) {
|
||||
this(code, DEFAULT_NAME);
|
||||
}
|
||||
public ReaderCodeLoader(Reader code) {
|
||||
this(code, DEFAULT_NAME);
|
||||
}
|
||||
|
||||
public ReaderCodeLoader(Reader code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
public ReaderCodeLoader(Reader code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getReader() {
|
||||
return code;
|
||||
}
|
||||
@Override
|
||||
public Reader getReader() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public String getFileName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private CodeLoader cl;
|
||||
|
||||
public SourceCode(CodeLoader cl) {
|
||||
this.cl = cl;
|
||||
this.cl = cl;
|
||||
}
|
||||
|
||||
public List<String> getCode() {
|
||||
return cl.getCode();
|
||||
return cl.getCode();
|
||||
}
|
||||
|
||||
public StringBuilder getCodeBuffer() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<String> lines = cl.getCode();
|
||||
for (String line : lines) {
|
||||
sb.append(line).append(PMD.EOL);
|
||||
}
|
||||
return sb;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<String> lines = cl.getCode();
|
||||
for (String line : lines) {
|
||||
sb.append(line).append(PMD.EOL);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
public String getSlice(int startLine, int endLine) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<String> lines = cl.getCode();
|
||||
for (int i = startLine == 0 ? startLine :startLine - 1; i < endLine && i < lines.size(); i++) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<String> lines = cl.getCode();
|
||||
for (int i = startLine == 0 ? startLine : startLine - 1; i < endLine && i < lines.size(); i++) {
|
||||
if (sb.length() != 0) {
|
||||
sb.append(PMD.EOL);
|
||||
}
|
||||
sb.append(lines.get(i));
|
||||
}
|
||||
return sb.toString();
|
||||
sb.append(PMD.EOL);
|
||||
}
|
||||
sb.append(lines.get(i));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return cl.getFileName();
|
||||
return cl.getFileName();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,13 @@ public interface Tokenizer {
|
||||
String IGNORE_LITERALS = "ignore_literals";
|
||||
String IGNORE_IDENTIFIERS = "ignore_identifiers";
|
||||
String IGNORE_ANNOTATIONS = "ignore_annotations";
|
||||
|
||||
/**
|
||||
* Ignore using directives in C#.
|
||||
* The default value is <code>false</code>.
|
||||
*/
|
||||
String IGNORE_USINGS = "ignore_usings";
|
||||
|
||||
/**
|
||||
* Enables or disabled skipping of blocks like a pre-processor.
|
||||
* It is a boolean property.
|
||||
|
||||
@@ -77,7 +77,7 @@ public final class XMLRenderer implements Renderer {
|
||||
transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "codefragment");
|
||||
StringWriter writer = new StringWriter();
|
||||
transformer.transform(new DOMSource(doc), new StreamResult(writer));
|
||||
return writer.getBuffer().toString();
|
||||
return writer.toString();
|
||||
} catch (TransformerException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
@@ -51,7 +53,11 @@ public class UsageGraphBuilder {
|
||||
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(
|
||||
classResourceName + ".class");
|
||||
ClassReader classReader = new ClassReader(inputStream);
|
||||
classReader.accept(getNewClassVisitor(), 0);
|
||||
try {
|
||||
classReader.accept(getNewClassVisitor(), 0);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.ServiceLoader;
|
||||
*/
|
||||
public final class LanguageRegistry {
|
||||
|
||||
private static LanguageRegistry instance;
|
||||
private static LanguageRegistry instance = new LanguageRegistry();
|
||||
|
||||
private Map<String, Language> languages;
|
||||
|
||||
@@ -27,10 +27,7 @@ public final class LanguageRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
protected static LanguageRegistry getInstance() {
|
||||
if(instance == null) {
|
||||
instance = new LanguageRegistry();
|
||||
}
|
||||
public static LanguageRegistry getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -57,13 +54,13 @@ public final class LanguageRegistry {
|
||||
|
||||
public static LanguageVersion findLanguageVersionByTerseName(String terseName) {
|
||||
String version = null;
|
||||
if(terseName.contains(" ")) {
|
||||
if (terseName.contains(" ")) {
|
||||
version = terseName.substring(terseName.lastIndexOf(' ') + 1);
|
||||
terseName = terseName.substring(0, terseName.lastIndexOf(' '));
|
||||
}
|
||||
Language language = findLanguageByTerseName(terseName);
|
||||
if(language != null) {
|
||||
if(version == null) {
|
||||
if (language != null) {
|
||||
if (version == null) {
|
||||
return language.getDefaultVersion();
|
||||
} else {
|
||||
return language.getVersion(version);
|
||||
@@ -84,8 +81,8 @@ public final class LanguageRegistry {
|
||||
|
||||
public static List<LanguageVersion> findAllVersions() {
|
||||
List<LanguageVersion> versions = new ArrayList<LanguageVersion>();
|
||||
for(Language language : getLanguages()) {
|
||||
for(LanguageVersion languageVersion : language.getVersions()) {
|
||||
for (Language language : getLanguages()) {
|
||||
for (LanguageVersion languageVersion : language.getVersions()) {
|
||||
versions.add(languageVersion);
|
||||
}
|
||||
}
|
||||
@@ -94,6 +91,7 @@ public final class LanguageRegistry {
|
||||
|
||||
/**
|
||||
* A utility method to find the Languages which have Rule support.
|
||||
*
|
||||
* @return A List of Languages with Rule support.
|
||||
*/
|
||||
public static List<Language> findWithRuleSupport() {
|
||||
@@ -124,7 +122,7 @@ public final class LanguageRegistry {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(languageVersions.get(0).getTerseName());
|
||||
for (int i=1; i<languageVersions.size(); i++) {
|
||||
for (int i = 1; i < languageVersions.size(); i++) {
|
||||
builder.append(", ").append(languageVersions.get(i).getTerseName());
|
||||
}
|
||||
return builder.toString();
|
||||
|
||||
@@ -14,6 +14,7 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.Attribute;
|
||||
import net.sourceforge.pmd.lang.ast.xpath.DocumentNavigator;
|
||||
import net.sourceforge.pmd.lang.dfa.DataFlowNode;
|
||||
import net.sourceforge.pmd.lang.ast.GenericToken;
|
||||
|
||||
import org.jaxen.BaseXPath;
|
||||
import org.jaxen.JaxenException;
|
||||
@@ -114,7 +115,7 @@ public abstract class AbstractNode implements Node {
|
||||
}
|
||||
|
||||
public boolean hasImageEqualTo(String image) {
|
||||
return this.image != null && this.image.equals(image);
|
||||
return this.getImage() != null && this.getImage().equals(image);
|
||||
}
|
||||
|
||||
public int getBeginLine() {
|
||||
@@ -397,4 +398,22 @@ public abstract class AbstractNode implements Node {
|
||||
public void setUserData(Object userData) {
|
||||
this.userData = userData;
|
||||
}
|
||||
|
||||
protected GenericToken firstToken, lastToken;
|
||||
|
||||
public GenericToken jjtGetFirstToken() {
|
||||
return firstToken;
|
||||
}
|
||||
|
||||
public void jjtSetFirstToken(GenericToken token) {
|
||||
this.firstToken = token;
|
||||
}
|
||||
|
||||
public GenericToken jjtGetLastToken() {
|
||||
return lastToken;
|
||||
}
|
||||
|
||||
public void jjtSetLastToken(GenericToken token) {
|
||||
this.lastToken = token;
|
||||
}
|
||||
}
|
||||
Loaded 30 of 326 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user