Merge branch 'master' into pmd/7.0.x

This commit is contained in:
Andreas Dangel
2020-11-23 16:00:01 +01:00
19 changed files with 265 additions and 112 deletions

View File

@ -169,8 +169,8 @@ and configuration errors are reported.
Example:
```
/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java:124: Logger calls should be surrounded by log level guards.
/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java:58: This for loop can be replaced by a foreach loop
/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java:124: GuardLogStatement: Logger calls should be surrounded by log level guards.
/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java:58: ForLoopCanBeForeach: This for loop can be replaced by a foreach loop
/home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java - PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
CloseResource rule violation suppressed by Annotation in /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java
LoosePackageCoupling - No packages or classes specified

View File

@ -21,8 +21,16 @@ This is a {{ site.pmd.release_type }} release.
### Fixed Issues
* pmd-core
* core
* [#1939](https://github.com/pmd/pmd/issues/1939): \[core] XPath expressions return handling
* [#1961](https://github.com/pmd/pmd/issues/1961): \[core] Text renderer should include name of violated rule
* [#2874](https://github.com/pmd/pmd/pull/2874): \[core] Fix XMLRenderer with UTF-16
* cs
* [#2938](https://github.com/pmd/pmd/pull/2938): \[cs] CPD: ignoring using directives could not be disabled
* java
* [#2911](https://github.com/pmd/pmd/issues/2911): \[java] `ClassTypeResolver#searchNodeNameForClass` leaks memory
* scala
* [#2480](https://github.com/pmd/pmd/issues/2480): \[scala] Support CPD suppressions
### API Changes
@ -53,4 +61,10 @@ You can identify them with the `@InternalApi` annotation. You'll also get a depr
### External Contributions
* [#2914](https://github.com/pmd/pmd/pull/2914): \[core] Include rule name in text renderer - [Gunther Schrijvers](https://github.com/GuntherSchrijvers)
* [#2925](https://github.com/pmd/pmd/pull/2925): Cleanup: Correct annotation array initializer indents from checkstyle #8083 - [Abhishek Kumar](https://github.com/Abhishek-kumar09)
* [#2929](https://github.com/pmd/pmd/pull/2929): \[scala] Add support for CPD-ON and CPD-OFF special comments - [Andy Robinson](https://github.com/andyrobinson)
* [#2936](https://github.com/pmd/pmd/pull/2936): \[java] (doc) Fix typo: "an accessor" not "a" - [Igor Moreno](https://github.com/igormoreno)
* [#2938](https://github.com/pmd/pmd/pull/2938): \[cs] CPD: fix issue where ignoring using directives could not be disabled - [Maikel Steneker](https://github.com/maikelsteneker)
{% endtocmaker %}

View File

@ -16,6 +16,10 @@ import net.sourceforge.pmd.RuleViolation;
*/
public class TextRenderer extends AbstractIncrementingRenderer {
private static final char SMALL_SEPARATOR = ':';
private static final String MEDIUM_SEPARATOR = ":\t";
private static final String LARGE_SEPARATOR = "\t-\t";
public static final String NAME = "text";
public TextRenderer() {
@ -35,8 +39,9 @@ public class TextRenderer extends AbstractIncrementingRenderer {
buf.setLength(0);
RuleViolation rv = violations.next();
buf.append(determineFileName(rv.getFilename()));
buf.append(':').append(rv.getBeginLine());
buf.append(":\t").append(rv.getDescription()).append(PMD.EOL);
buf.append(SMALL_SEPARATOR).append(rv.getBeginLine());
buf.append(MEDIUM_SEPARATOR).append(rv.getRule().getName());
buf.append(MEDIUM_SEPARATOR).append(rv.getDescription()).append(PMD.EOL);
writer.write(buf.toString());
}
}
@ -48,7 +53,7 @@ public class TextRenderer extends AbstractIncrementingRenderer {
for (Report.ProcessingError error : errors) {
buf.setLength(0);
buf.append(determineFileName(error.getFile()));
buf.append("\t-\t").append(error.getMsg()).append(PMD.EOL);
buf.append(LARGE_SEPARATOR).append(error.getMsg()).append(PMD.EOL);
writer.write(buf.toString());
}
@ -66,7 +71,7 @@ public class TextRenderer extends AbstractIncrementingRenderer {
for (Report.ConfigurationError error : configErrors) {
buf.setLength(0);
buf.append(error.rule().getName());
buf.append("\t-\t").append(error.issue()).append(PMD.EOL);
buf.append(LARGE_SEPARATOR).append(error.issue()).append(PMD.EOL);
writer.write(buf.toString());
}
}

View File

@ -10,6 +10,8 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -68,7 +70,8 @@ public class XMLRenderer extends AbstractIncrementingRenderer {
@Override
public void start() throws IOException {
String encoding = getProperty(ENCODING);
lineSeparator = PMD.EOL.getBytes(encoding);
String unmarkedEncoding = toUnmarkedEncoding(encoding);
lineSeparator = PMD.EOL.getBytes(unmarkedEncoding);
try {
xmlWriter.writeStartDocument(encoding, "1.0");
@ -88,6 +91,26 @@ public class XMLRenderer extends AbstractIncrementingRenderer {
}
}
/**
* Return a encoding, which doesn't write a BOM (byte order mark).
* Only UTF-16 encoders might write a BOM, see {@link Charset}.
*
* <p>This is needed, so that we don't accidentally add BOMs whenever
* we insert a newline.
*
* @return
*/
private static String toUnmarkedEncoding(String encoding) {
if (StandardCharsets.UTF_16.name().equalsIgnoreCase(encoding)) {
return StandardCharsets.UTF_16BE.name();
}
// edge case: UTF-16LE with BOM
if ("UTF-16LE_BOM".equalsIgnoreCase(encoding)) {
return StandardCharsets.UTF_16LE.name();
}
return encoding;
}
/**
* Outputs a platform dependent line separator.
*

View File

@ -78,7 +78,7 @@ public class PMDTaskTest {
String actual = IOUtils.toString(in, StandardCharsets.UTF_8);
// remove any trailing newline
actual = actual.replaceAll("\n|\r", "");
Assert.assertEquals("sample.dummy:1:\tTest Rule 2", actual);
Assert.assertEquals("sample.dummy:1:\tSampleXPathRule:\tTest Rule 2", actual);
}
}
}

View File

@ -15,18 +15,18 @@ import org.junit.runners.Suite.SuiteClasses;
*/
@RunWith(Suite.class)
@SuiteClasses({
CodeClimateRendererTest.class,
CSVRendererTest.class,
EmacsRendererTest.class,
HTMLRendererTest.class,
IDEAJRendererTest.class,
PapariTextRendererTest.class,
SummaryHTMLRendererTest.class,
TextPadRendererTest.class,
VBHTMLRendererTest.class,
XMLRendererTest.class,
XSLTRendererTest.class,
YAHTMLRendererTest.class
CodeClimateRendererTest.class,
CSVRendererTest.class,
EmacsRendererTest.class,
HTMLRendererTest.class,
IDEAJRendererTest.class,
PapariTextRendererTest.class,
SummaryHTMLRendererTest.class,
TextPadRendererTest.class,
VBHTMLRendererTest.class,
XMLRendererTest.class,
XSLTRendererTest.class,
YAHTMLRendererTest.class
})
public class RenderersTests {
}

View File

@ -17,7 +17,7 @@ public class TextRendererTest extends AbstractRendererTest {
@Override
public String getExpected() {
return getSourceCodeFilename() + ":1:\tblah" + PMD.EOL;
return getSourceCodeFilename() + ":1:\tFoo:\tblah" + PMD.EOL;
}
@Override
@ -27,8 +27,8 @@ public class TextRendererTest extends AbstractRendererTest {
@Override
public String getExpectedMultiple() {
return getSourceCodeFilename() + ":1:\tblah" + PMD.EOL
+ getSourceCodeFilename() + ":1:\tblah" + PMD.EOL;
return getSourceCodeFilename() + ":1:\tFoo:\tblah" + PMD.EOL
+ getSourceCodeFilename() + ":1:\tFoo:\tblah" + PMD.EOL;
}
@Override

View File

@ -116,6 +116,12 @@ public class XMLRendererTest extends AbstractRendererTest {
verifyXmlEscaping(renderer, "\ud801\udc1c", StandardCharsets.UTF_8);
}
@Test
public void testXMLEscapingWithUTF16() throws Exception {
Renderer renderer = getRenderer();
verifyXmlEscaping(renderer, "&#x1041c;", StandardCharsets.UTF_16);
}
@Test
public void testXMLEscapingWithoutUTF8() throws Exception {
Renderer renderer = getRenderer();

View File

@ -22,9 +22,7 @@ public class CsTokenizer extends AntlrTokenizer {
private boolean ignoreUsings = false;
public void setProperties(Properties properties) {
if (properties.containsKey(IGNORE_USINGS)) {
ignoreUsings = Boolean.parseBoolean(properties.getProperty(IGNORE_USINGS, "false"));
}
ignoreUsings = Boolean.parseBoolean(properties.getProperty(IGNORE_USINGS, "false"));
}
public void setIgnoreUsings(boolean ignoreUsings) {

View File

@ -71,7 +71,7 @@ public class Outer {
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AccessorMethodGenerationRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#accessormethodgeneration">
<description>
When accessing a private field / method from another class, the Java compiler will generate a accessor methods
When accessing private fields / methods from another class, the Java compiler will generate accessor methods
with package-private visibility. This adds overhead, and to the dex method count on Android. This situation can
be avoided by changing the visibility of the field / method from private to package-private.
</description>

View File

@ -29,7 +29,7 @@ public class Foo { // class Bar
@AnnotationWithParams({@Nested(1) ,
@Nested(2) ,
@Nested
})
})
public void foo() {
}

View File

@ -4,8 +4,8 @@ package foo.bar.baz;
// another irrelevant comment
@ MyAnnotation ("ugh")
@NamedQueries({
@NamedQuery(
)})
@NamedQuery(
)})
public class Foo {// CPD-ON

View File

@ -0,0 +1,66 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.cpd;
import net.sourceforge.pmd.lang.ast.GenericToken;
import scala.meta.tokens.Token;
/**
* Adapts the scala.meta.tokens.Token so that it can be used with the generic BaseTokenFilter
*/
public class ScalaTokenAdapter implements GenericToken {
private Token token;
private GenericToken previousComment;
ScalaTokenAdapter(Token token, GenericToken comment) {
this.token = token;
this.previousComment = comment;
}
@Override
public GenericToken getNext() {
throw new UnsupportedOperationException();
}
@Override
public GenericToken getPreviousComment() {
return previousComment;
}
@Override
public String getImage() {
return token.text();
}
@Override
public int getBeginLine() {
return token.pos().startLine() + 1;
}
@Override
public int getEndLine() {
return token.pos().endLine() + 1;
}
@Override
public int getBeginColumn() {
return token.pos().startColumn() + 1;
}
@Override
public int getEndColumn() {
return token.pos().endColumn() + 2;
}
@Override
public String toString() {
return "ScalaTokenAdapter{"
+ "token=" + token
+ ", previousComment=" + previousComment
+ "}";
}
}

View File

@ -9,8 +9,11 @@ import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.cpd.token.internal.BaseTokenFilter;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.TokenManager;
import net.sourceforge.pmd.lang.ast.GenericToken;
import net.sourceforge.pmd.lang.ast.TokenMgrError;
import net.sourceforge.pmd.lang.scala.ScalaLanguageHandler;
import net.sourceforge.pmd.lang.scala.ScalaLanguageModule;
@ -24,7 +27,7 @@ import scala.meta.tokenizers.TokenizeException;
import scala.meta.tokens.Token;
/**
* Scala Tokenizer class. Uses the Scala Meta Tokenizer.
* Scala Tokenizer class. Uses the Scala Meta Tokenizer, but adapts it for use with generic filtering
*/
public class ScalaTokenizer implements Tokenizer {
@ -72,19 +75,21 @@ public class ScalaTokenizer implements Tokenizer {
// tokenize with a filter
try {
scala.meta.tokens.Tokens tokens = tokenizer.tokenize();
ScalaTokenFilter filter = new ScalaTokenFilter(tokens.iterator());
Token token;
// use extensions to the standard PMD TokenManager and Filter
ScalaTokenManager scalaTokenManager = new ScalaTokenManager(tokens.iterator());
ScalaTokenFilter filter = new ScalaTokenFilter(scalaTokenManager);
GenericToken token;
while ((token = filter.getNextToken()) != null) {
if (StringUtils.isEmpty(token.text())) {
if (StringUtils.isEmpty(token.getImage())) {
continue;
}
Position pos = token.pos();
TokenEntry cpdToken = new TokenEntry(token.text(),
TokenEntry cpdToken = new TokenEntry(token.getImage(),
filename,
pos.startLine() + 1,
pos.startColumn() + 1,
pos.endColumn() + 2);
token.getBeginLine(),
token.getBeginColumn(),
token.getEndColumn());
tokenEntries.add(cpdToken);
}
} catch (Exception e) {
@ -103,19 +108,25 @@ public class ScalaTokenizer implements Tokenizer {
}
/**
* Token Filter skips un-helpful tokens to only register important tokens
* Implementation of the generic Token Manager, also skips un-helpful tokens and comments to only register important tokens
* and patterns.
*
* Keeps track of comments, for special comment processing
*/
private static class ScalaTokenFilter {
private static class ScalaTokenManager implements TokenManager {
Iterator<Token> tokenIter;
Class<?>[] skippableTokens = new Class<?>[] { Token.Space.class, Token.Tab.class, Token.CR.class,
Token.LF.class, Token.FF.class, Token.LFLF.class, Token.EOF.class };
Token.LF.class, Token.FF.class, Token.LFLF.class, Token.EOF.class, Token.Comment.class };
ScalaTokenFilter(Iterator<Token> iterator) {
GenericToken previousComment = null;
ScalaTokenManager(Iterator<Token> iterator) {
this.tokenIter = iterator;
}
Token getNextToken() {
@Override
public GenericToken getNextToken() {
if (!tokenIter.hasNext()) {
return null;
}
@ -123,9 +134,12 @@ public class ScalaTokenizer implements Tokenizer {
Token token;
do {
token = tokenIter.next();
if (isComment(token)) {
previousComment = new ScalaTokenAdapter(token, previousComment);
}
} while (token != null && skipToken(token) && tokenIter.hasNext());
return token;
return new ScalaTokenAdapter(token, previousComment);
}
private boolean skipToken(Token token) {
@ -137,5 +151,27 @@ public class ScalaTokenizer implements Tokenizer {
}
return skip;
}
private boolean isComment(Token token) {
return token instanceof Token.Comment;
}
@Override
public void setFileName(String fileName) {
throw new UnsupportedOperationException("setFileName deprecated");
}
}
private static class ScalaTokenFilter extends BaseTokenFilter<ScalaTokenAdapter> {
ScalaTokenFilter(TokenManager tokenManager) {
super(tokenManager);
}
@Override
protected boolean shouldStopProcessing(ScalaTokenAdapter currentToken) {
return currentToken == null;
}
}
}

View File

@ -36,6 +36,11 @@ public class ScalaTokenizerTest extends CpdTextComparisonTest {
doTest("sample-LiftActor");
}
@Test
public void testSuppressionComments() {
doTest("special_comments");
}
@Test
public void tokenizeFailTest() {
ex.expect(TokenMgrError.class);

View File

@ -1,6 +1,4 @@
[Image] or [Truncated image[ Bcol Ecol
L1
[/* Example source code copied from[ 1 5
L19
[package] 1 9
[net] 9 13
@ -40,14 +38,10 @@ L26
[Unit] 19 24
L27
[}] 1 3
L29
[/**\n * The definition of a schedu[ 1 5
L32
[trait] 1 7
[LAScheduler] 7 19
[{] 19 21
L33
[/**\n * Execute some code on ano[ 3 7
L38
[def] 3 7
[execute] 7 15
@ -79,8 +73,6 @@ L43
[onSameThread] 7 20
[=] 20 22
[false] 22 28
L45
[/**\n * Set this variable to the[ 3 7
L48
[@] 3 5
[volatile] 4 13
@ -98,8 +90,6 @@ L50
[threadPoolSize] 37 52
[*] 52 54
[25] 54 57
L52
[/**\n * If it's Full, then creat[ 3 7
L57
[@] 3 5
[volatile] 4 13
@ -149,7 +139,6 @@ L64
[val] 15 19
[es] 19 22
[=] 22 24
[// Executors.newFixedThreadPool(th[ 24 72
L65
[new] 9 13
[ThreadPoolExecutor] 13 32
@ -282,8 +271,6 @@ L91
[ILAExecute] 13 24
[=] 24 26
[_] 26 28
L93
[/**\n * Execute some code on ano[ 3 7
L98
[def] 3 7
[execute] 7 15
@ -464,8 +451,6 @@ L127
[MailboxItem] 15 27
[=] 27 29
[_] 29 31
L129
[/*\n def find(f: MailboxItem =>[ 5 8
L134
[def] 5 9
[remove] 9 16
@ -588,8 +573,6 @@ L157
[\]] 71 73
[)] 72 74
[{] 74 76
L158
[// override def find(f: MailboxIte[ 5 79
L159
[next] 5 10
[=] 10 12
@ -659,8 +642,6 @@ L167
[)] 42 44
L168
[}] 5 7
L170
[/**\n * Send a message to the Ac[ 3 7
L175
[def] 3 7
[send] 7 12
@ -675,8 +656,6 @@ L175
[this] 28 33
[!] 33 35
[msg] 35 39
L177
[/**\n * Send a message to the Ac[ 3 7
L182
[def] 3 7
[!] 7 9
@ -793,8 +772,6 @@ L199
[)] 10 12
L200
[}] 3 5
L202
[/**\n * This method inserts the [ 3 7
L207
[protected] 3 13
[def] 13 17
@ -936,8 +913,6 @@ L230
[}] 5 7
L231
[}] 3 5
L233
[/**\n * A list of LoanWrappers t[ 3 7
L236
[protected] 3 13
[def] 13 17
@ -949,8 +924,6 @@ L236
[\]] 52 54
[=] 54 56
[Nil] 56 60
L238
[/**\n * You can wrap calls aroun[ 3 7
L242
[protected] 3 13
[def] 13 17
@ -1574,8 +1547,6 @@ L349
[}] 3 5
L350
[}] 1 3
L352
[/**\n * A SpecializedLiftActor des[ 1 5
L362
[class] 1 7
[MockSpecializedLiftActor] 7 32
@ -1602,8 +1573,6 @@ L363
[\]] 45 47
[=] 47 49
[Nil] 49 53
L365
[/**\n * Send a message to the mo[ 3 7
L369
[override] 3 12
[def] 12 16
@ -1630,10 +1599,6 @@ L372
[}] 5 7
L373
[}] 3 5
L375
[// We aren't required to implement[ 3 80
L376
[// since the message handler never[ 3 44
L377
[override] 3 12
[def] 12 16
@ -1653,8 +1618,6 @@ L378
[=>] 12 15
L379
[}] 3 5
L381
[/**\n * Test to see if this acto[ 3 7
L384
[def] 3 7
[hasReceivedMessage_?] 7 28
@ -1672,8 +1635,6 @@ L384
[(] 72 74
[msg] 73 77
[)] 76 78
L386
[/**\n * Returns the list of mess[ 3 7
L389
[def] 3 7
[messages] 7 16
@ -1684,8 +1645,6 @@ L389
[\]] 23 25
[=] 25 27
[messagesReceived] 27 44
L391
[/**\n * Return the number of mes[ 3 7
L394
[def] 3 7
[messageCount] 7 20
@ -1830,8 +1789,6 @@ L417
[msg] 24 28
L418
[}] 3 5
L420
[/**\n * Send a message to the Act[ 3 6
L425
[def] 3 7
[sendAndGetFuture] 7 24
@ -1849,8 +1806,6 @@ L425
[this] 51 56
[!<] 56 59
[msg] 59 63
L427
[/**\n * Send a message to the Act[ 3 6
L431
[def] 3 7
[!<] 7 10
@ -1888,8 +1843,6 @@ L434
[future] 5 12
L435
[}] 3 5
L437
[/**\n * Send a message to the Act[ 3 6
L442
[def] 3 7
[sendAndGetReply] 7 23
@ -1904,8 +1857,6 @@ L442
[this] 40 45
[!?] 45 48
[msg] 48 52
L444
[/**\n * Send a message to the Act[ 3 6
L448
[def] 3 7
[!?] 7 10
@ -1942,8 +1893,6 @@ L451
[get] 12 16
L452
[}] 3 5
L455
[/**\n * Send a message to the Act[ 3 6
L461
[def] 3 7
[sendAndGetReply] 7 23
@ -1967,8 +1916,6 @@ L461
[,] 70 72
[msg] 72 76
[)] 75 77
L463
[/**\n * Send a message to the Act[ 3 6
L468
[def] 3 7
[!?] 7 10
@ -1995,8 +1942,6 @@ L469
[,] 21 23
[timeout] 23 31
[)] 30 32
L472
[/**\n * Send a message to the A[ 5 8
L477
[def] 3 7
[!!] 7 10
@ -2043,8 +1988,6 @@ L480
[)] 23 25
L481
[}] 3 5
L483
[/**\n * Send a message to the Act[ 3 6
L487
[def] 3 7
[!!] 7 10
@ -2193,8 +2136,6 @@ L506
[)] 18 20
L507
[}] 3 5
L509
[/**\n * The Actor should call thi[ 3 6
L513
[protected] 3 13
[def] 13 17
@ -2226,8 +2167,6 @@ L517
[}] 3 5
L518
[}] 1 3
L520
[/**\n * A MockLiftActor for use in[ 1 5
L529
[class] 1 7
[MockLiftActor] 7 21
@ -2503,7 +2442,6 @@ L565
[(] 24 26
[true] 25 30
[)] 29 31
[// access private and protected me[ 31 71
L566
[m] 9 11
[.] 10 12
@ -2826,8 +2764,6 @@ L604
[}] 5 7
L605
[}] 1 3
L607
[/**\n * Java versions of Actors sh[ 1 5
L612
[class] 1 7
[LiftActorJ] 7 18

View File

@ -0,0 +1,24 @@
// Testing CPD suppression
// Irrelevant comment
// CPD-OFF
// CPD-ON
case class Foo() { // special multiline comments
/* CPD-OFF
*
*
* */ val hi = "Hello" /* This is a comment ending in CPD-ON */
private def bar(i: Int) : Int = {
val CPD = 40
val OFF = 60
CPD-OFF // This should tokenize
}
/* CPD-OFF */
def bar2(s: String): String = "bar2"
/* CPD-ON */
}

View File

@ -0,0 +1,40 @@
[Image] or [Truncated image[ Bcol Ecol
L7
[case] 1 6
[class] 6 12
[Foo] 12 16
[(] 15 17
[)] 16 18
[{] 18 20
L14
[private] 3 11
[def] 11 15
[bar] 15 19
[(] 18 20
[i] 19 21
[:] 20 22
[Int] 22 26
[)] 25 27
[:] 27 29
[Int] 29 33
[=] 33 35
[{] 35 37
L15
[val] 5 9
[CPD] 9 13
[=] 13 15
[40] 15 18
L16
[val] 5 9
[OFF] 9 13
[=] 13 15
[60] 15 18
L17
[CPD] 5 9
[-] 8 10
[OFF] 9 13
L18
[}] 3 5
L24
[}] 1 3
EOF

View File

@ -94,7 +94,7 @@
<surefire.version>3.0.0-M5</surefire.version>
<checkstyle.version>8.30</checkstyle.version>
<checkstyle.plugin.version>3.1.1</checkstyle.plugin.version>
<pmd.plugin.version>3.13.0</pmd.plugin.version>
<pmd.plugin.version>3.14.0</pmd.plugin.version>
<ant.version>1.10.8</ant.version>
<javadoc.plugin.version>3.2.0</javadoc.plugin.version>
<antlr.version>4.7.2</antlr.version>
@ -320,7 +320,7 @@
<detectOfflineLinks>false</detectOfflineLinks>
<offlineLinks>
<offlineLink>
<location>${project.basedir}/../pmd-lang-test/target/dokka/pmd-lang-test</location>
<location>${project.basedir}/../pmd-lang-test/target/dokkaJavadocJar</location>
<url>../../pmd-lang-test/${project.version}</url>
</offlineLink>
<offlineLink>