From aa54194d19044781274b2c9bdf6634ebcb0e06d2 Mon Sep 17 00:00:00 2001 From: Matias Fraga Date: Sun, 9 Sep 2018 21:51:43 -0300 Subject: [PATCH 1/6] Initial implementation of GenericToken for antlr languages --- .../pmd/cpd/token/GenericAntlrToken.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java new file mode 100644 index 0000000000..97d07683a9 --- /dev/null +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java @@ -0,0 +1,61 @@ +package net.sourceforge.pmd.cpd.token; + +import net.sourceforge.pmd.lang.ast.GenericToken; +import org.antlr.v4.runtime.Token; + +/** + * Generic Antlr representation of a token. + */ +public class GenericAntlrToken implements GenericToken { + + private final Token token; + private final GenericAntlrToken previousComment; + + /** + * Constructor + * + * @param token The antlr token implementation + * @param previousComment The previous comment + */ + public GenericAntlrToken(final Token token, final GenericAntlrToken previousComment) { + this.token = token; + this.previousComment = previousComment; + } + + + @Override + public GenericToken getNext() { + // Antlr implementation does not require this + return null; + } + + @Override + public GenericToken getPreviousComment() { + return previousComment; + } + + @Override + public String getImage() { + return token.getText(); + } + + @Override + public int getBeginLine() { + return token.getLine(); + } + + @Override + public int getEndLine() { + return token.getLine(); // TODO: review this + } + + @Override + public int getBeginColumn() { + return token.getCharPositionInLine(); + } + + @Override + public int getEndColumn() { + return token.getCharPositionInLine() + token.getStopIndex() - token.getStartIndex(); + } +} From c7dfac35492a221627004a5939f53c63683ad95f Mon Sep 17 00:00:00 2001 From: Matias Fraga Date: Mon, 10 Sep 2018 00:39:07 -0300 Subject: [PATCH 2/6] Expand generic token --- .../sourceforge/pmd/cpd/AntlrTokenizer.java | 7 ++++--- .../pmd/cpd/token/GenericAntlrToken.java | 21 +++++++++++++++++-- .../pmd/lang/AntlrTokenManager.java | 21 +++++++++++++++++-- .../sourceforge/pmd/cpd/SwiftTokenizer.java | 7 ++++++- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java index 8dcc643b94..0b1cdaef32 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java @@ -9,6 +9,7 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.Token; +import net.sourceforge.pmd.cpd.token.GenericAntlrToken; import net.sourceforge.pmd.lang.AntlrTokenManager; import net.sourceforge.pmd.lang.ast.TokenMgrError; @@ -26,16 +27,16 @@ public abstract class AntlrTokenizer implements Tokenizer { tokenManager.resetListeners(); try { - Token token = (Token) tokenManager.getNextToken(); + GenericAntlrToken token = (GenericAntlrToken) tokenManager.getNextToken(); while (token.getType() != Token.EOF) { if (token.getChannel() != Lexer.HIDDEN) { final TokenEntry tokenEntry = - new TokenEntry(token.getText(), tokenManager.getFileName(), token.getLine()); + new TokenEntry(token.getImage(), tokenManager.getFileName(), token.getBeginLine()); tokenEntries.add(tokenEntry); } - token = (Token) tokenManager.getNextToken(); + token = (GenericAntlrToken) tokenManager.getNextToken(); } } catch (final AntlrTokenManager.ANTLRSyntaxError err) { // Wrap exceptions of the ANTLR tokenizer in a TokenMgrError, so they are correctly handled diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java index 97d07683a9..4405fd0548 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java @@ -1,5 +1,6 @@ package net.sourceforge.pmd.cpd.token; +import com.beust.jcommander.internal.Nullable; import net.sourceforge.pmd.lang.ast.GenericToken; import org.antlr.v4.runtime.Token; @@ -11,18 +12,26 @@ public class GenericAntlrToken implements GenericToken { private final Token token; private final GenericAntlrToken previousComment; + /** + * Constructor + * + * @param token The antlr token implementation + */ + public GenericAntlrToken(final Token token) { + this(token, null); + } + /** * Constructor * * @param token The antlr token implementation * @param previousComment The previous comment */ - public GenericAntlrToken(final Token token, final GenericAntlrToken previousComment) { + public GenericAntlrToken(final Token token, @Nullable final GenericAntlrToken previousComment) { this.token = token; this.previousComment = previousComment; } - @Override public GenericToken getNext() { // Antlr implementation does not require this @@ -58,4 +67,12 @@ public class GenericAntlrToken implements GenericToken { public int getEndColumn() { return token.getCharPositionInLine() + token.getStopIndex() - token.getStartIndex(); } + + public int getType() { + return token.getType(); + } + + public int getChannel() { + return token.getChannel(); + } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java index c6724899ac..b9faeb3a2e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java @@ -8,6 +8,10 @@ import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; +import org.antlr.v4.runtime.Token; + +import com.beust.jcommander.internal.Nullable; +import net.sourceforge.pmd.cpd.token.GenericAntlrToken; /** * Generic token manager implementation for all Antlr lexers. @@ -15,21 +19,30 @@ import org.antlr.v4.runtime.Recognizer; public class AntlrTokenManager implements TokenManager { private final Lexer lexer; private String fileName; + private final String commentToken; + private GenericAntlrToken previousComment; /** * Constructor * * @param lexer The lexer * @param fileName The file name + * @param commentToken The list of all comment tokens on the grammar */ - public AntlrTokenManager(final Lexer lexer, final String fileName) { + public AntlrTokenManager(final Lexer lexer, final String fileName, @Nullable final String commentToken) { this.lexer = lexer; this.fileName = fileName; + this.commentToken = commentToken; } @Override public Object getNextToken() { - return lexer.nextToken(); + final Token token = lexer.nextToken(); + if (isCommentToken(token.getText())) { + previousComment = new GenericAntlrToken(token); + } + + return new GenericAntlrToken(token, previousComment); } @Override @@ -46,6 +59,10 @@ public class AntlrTokenManager implements TokenManager { lexer.addErrorListener(new ErrorHandler()); } + private boolean isCommentToken(final String text) { + return commentToken != null && text != null && text.startsWith(commentToken); + + } private static class ErrorHandler extends BaseErrorListener { diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java index cb5a11b96e..add4f9f323 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java @@ -9,14 +9,19 @@ import org.antlr.v4.runtime.CharStream; import net.sourceforge.pmd.lang.AntlrTokenManager; import net.sourceforge.pmd.lang.swift.antlr4.SwiftLexer; +import java.util.ArrayList; +import java.util.List; + /** * SwiftTokenizer */ public class SwiftTokenizer extends AntlrTokenizer { + private static final String COMMENT_TOKEN = "//"; + @Override protected AntlrTokenManager getLexerForSource(final SourceCode sourceCode) { CharStream charStream = AntlrTokenizer.getCharStreamFromSourceCode(sourceCode); - return new AntlrTokenManager(new SwiftLexer(charStream), sourceCode.getFileName()); + return new AntlrTokenManager(new SwiftLexer(charStream), sourceCode.getFileName(), COMMENT_TOKEN); } } From e55f6bc63b110172e82485a88e59be3793d53de3 Mon Sep 17 00:00:00 2001 From: Matias Fraga Date: Mon, 10 Sep 2018 01:14:59 -0300 Subject: [PATCH 3/6] Fix checkstyle issues --- .../sourceforge/pmd/cpd/token/GenericAntlrToken.java | 12 +++++++++--- .../net/sourceforge/pmd/lang/AntlrTokenManager.java | 4 ++-- .../java/net/sourceforge/pmd/cpd/SwiftTokenizer.java | 3 --- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java index 4405fd0548..433a0d973e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java @@ -1,9 +1,15 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + package net.sourceforge.pmd.cpd.token; -import com.beust.jcommander.internal.Nullable; -import net.sourceforge.pmd.lang.ast.GenericToken; import org.antlr.v4.runtime.Token; +import net.sourceforge.pmd.lang.ast.GenericToken; + +import com.beust.jcommander.internal.Nullable; + /** * Generic Antlr representation of a token. */ @@ -55,7 +61,7 @@ public class GenericAntlrToken implements GenericToken { @Override public int getEndLine() { - return token.getLine(); // TODO: review this + return token.getLine(); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java index b9faeb3a2e..ea3234ecec 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java @@ -10,9 +10,10 @@ import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.Token; -import com.beust.jcommander.internal.Nullable; import net.sourceforge.pmd.cpd.token.GenericAntlrToken; +import com.beust.jcommander.internal.Nullable; + /** * Generic token manager implementation for all Antlr lexers. */ @@ -61,7 +62,6 @@ public class AntlrTokenManager implements TokenManager { private boolean isCommentToken(final String text) { return commentToken != null && text != null && text.startsWith(commentToken); - } private static class ErrorHandler extends BaseErrorListener { diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java index add4f9f323..9fefcd9f0c 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java @@ -9,9 +9,6 @@ import org.antlr.v4.runtime.CharStream; import net.sourceforge.pmd.lang.AntlrTokenManager; import net.sourceforge.pmd.lang.swift.antlr4.SwiftLexer; -import java.util.ArrayList; -import java.util.List; - /** * SwiftTokenizer */ From 5aa4d68c353b4dc41c1cdcae4e386fff0e406168 Mon Sep 17 00:00:00 2001 From: Matias Fraga Date: Mon, 10 Sep 2018 01:42:15 -0300 Subject: [PATCH 4/6] Keep the full list of previous comments --- .../net/sourceforge/pmd/cpd/token/GenericAntlrToken.java | 9 --------- .../java/net/sourceforge/pmd/lang/AntlrTokenManager.java | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java index 433a0d973e..85336524c2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java @@ -18,15 +18,6 @@ public class GenericAntlrToken implements GenericToken { private final Token token; private final GenericAntlrToken previousComment; - /** - * Constructor - * - * @param token The antlr token implementation - */ - public GenericAntlrToken(final Token token) { - this(token, null); - } - /** * Constructor * diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java index ea3234ecec..482f35eadd 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/AntlrTokenManager.java @@ -40,7 +40,7 @@ public class AntlrTokenManager implements TokenManager { public Object getNextToken() { final Token token = lexer.nextToken(); if (isCommentToken(token.getText())) { - previousComment = new GenericAntlrToken(token); + previousComment = new GenericAntlrToken(token, previousComment); } return new GenericAntlrToken(token, previousComment); From 7d65081841f7ec09c13d712d3dc0949630d0c66a Mon Sep 17 00:00:00 2001 From: Tomi De Lucca Date: Sun, 14 Oct 2018 19:02:15 -0300 Subject: [PATCH 5/6] PR Review --- .../sourceforge/pmd/cpd/AntlrTokenizer.java | 9 +++---- ...GenericAntlrToken.java => AntlrToken.java} | 11 ++++---- .../pmd/lang/antlr/AntlrTokenManager.java | 26 +++++-------------- .../sourceforge/pmd/cpd/SwiftTokenizer.java | 4 +-- 4 files changed, 18 insertions(+), 32 deletions(-) rename pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/{GenericAntlrToken.java => AntlrToken.java} (82%) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java index 60a7aab98d..aad0d2379a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/AntlrTokenizer.java @@ -6,10 +6,9 @@ package net.sourceforge.pmd.cpd; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.Token; -import net.sourceforge.pmd.cpd.token.GenericAntlrToken; +import net.sourceforge.pmd.cpd.token.AntlrToken; import net.sourceforge.pmd.lang.antlr.AntlrTokenManager; import net.sourceforge.pmd.lang.ast.TokenMgrError; @@ -26,16 +25,16 @@ public abstract class AntlrTokenizer implements Tokenizer { AntlrTokenManager tokenManager = getLexerForSource(sourceCode); try { - GenericAntlrToken token = (GenericAntlrToken) tokenManager.getNextToken(); + AntlrToken token = (AntlrToken) tokenManager.getNextToken(); while (token.getType() != Token.EOF) { - if (token.getChannel() != Lexer.HIDDEN) { + if (!token.isHidden()) { final TokenEntry tokenEntry = new TokenEntry(token.getImage(), tokenManager.getFileName(), token.getBeginLine()); tokenEntries.add(tokenEntry); } - token = (GenericAntlrToken) tokenManager.getNextToken(); + token = (AntlrToken) tokenManager.getNextToken(); } } catch (final AntlrTokenManager.ANTLRSyntaxError err) { // Wrap exceptions of the ANTLR tokenizer in a TokenMgrError, so they are correctly handled diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/AntlrToken.java similarity index 82% rename from pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java rename to pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/AntlrToken.java index 85336524c2..7eccf76126 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/GenericAntlrToken.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/token/AntlrToken.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.cpd.token; +import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.Token; import net.sourceforge.pmd.lang.ast.GenericToken; @@ -13,10 +14,10 @@ import com.beust.jcommander.internal.Nullable; /** * Generic Antlr representation of a token. */ -public class GenericAntlrToken implements GenericToken { +public class AntlrToken implements GenericToken { private final Token token; - private final GenericAntlrToken previousComment; + private final AntlrToken previousComment; /** * Constructor @@ -24,7 +25,7 @@ public class GenericAntlrToken implements GenericToken { * @param token The antlr token implementation * @param previousComment The previous comment */ - public GenericAntlrToken(final Token token, @Nullable final GenericAntlrToken previousComment) { + public AntlrToken(final Token token, @Nullable final AntlrToken previousComment) { this.token = token; this.previousComment = previousComment; } @@ -69,7 +70,7 @@ public class GenericAntlrToken implements GenericToken { return token.getType(); } - public int getChannel() { - return token.getChannel(); + public boolean isHidden() { + return token.getChannel() == Lexer.HIDDEN; } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/antlr/AntlrTokenManager.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/antlr/AntlrTokenManager.java index 789b0f555f..0bf95b3336 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/antlr/AntlrTokenManager.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/antlr/AntlrTokenManager.java @@ -8,12 +8,8 @@ import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; - -import net.sourceforge.pmd.cpd.token.GenericAntlrToken; - -import com.beust.jcommander.internal.Nullable; +import net.sourceforge.pmd.cpd.token.AntlrToken; import net.sourceforge.pmd.lang.TokenManager; /** @@ -22,31 +18,27 @@ import net.sourceforge.pmd.lang.TokenManager; public class AntlrTokenManager implements TokenManager { private final Lexer lexer; private String fileName; - private final String commentToken; - private GenericAntlrToken previousComment; + private AntlrToken previousToken; /** * Constructor * * @param lexer The lexer * @param fileName The file name - * @param commentToken The list of all comment tokens on the grammar */ - public AntlrTokenManager(final Lexer lexer, final String fileName, @Nullable final String commentToken) { + public AntlrTokenManager(final Lexer lexer, final String fileName) { this.lexer = lexer; this.fileName = fileName; - this.commentToken = commentToken; resetListeners(); } @Override public Object getNextToken() { - final Token token = lexer.nextToken(); - if (isCommentToken(token.getText())) { - previousComment = new GenericAntlrToken(token, previousComment); - } + final AntlrToken previousComment = previousToken != null && previousToken.isHidden() ? previousToken : null; + final AntlrToken currentToken = new AntlrToken(lexer.nextToken(), previousComment); + previousToken = currentToken; - return new GenericAntlrToken(token, previousComment); + return currentToken; } @Override @@ -63,10 +55,6 @@ public class AntlrTokenManager implements TokenManager { lexer.addErrorListener(new ErrorHandler()); } - private boolean isCommentToken(final String text) { - return commentToken != null && text != null && text.startsWith(commentToken); - } - private static class ErrorHandler extends BaseErrorListener { @Override diff --git a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java index b7063a0d6d..d97b1e6426 100644 --- a/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java +++ b/pmd-swift/src/main/java/net/sourceforge/pmd/cpd/SwiftTokenizer.java @@ -14,11 +14,9 @@ import net.sourceforge.pmd.lang.swift.antlr4.SwiftLexer; */ public class SwiftTokenizer extends AntlrTokenizer { - private static final String COMMENT_TOKEN = "//"; - @Override protected AntlrTokenManager getLexerForSource(final SourceCode sourceCode) { CharStream charStream = AntlrTokenizer.getCharStreamFromSourceCode(sourceCode); - return new AntlrTokenManager(new SwiftLexer(charStream), sourceCode.getFileName(), COMMENT_TOKEN); + return new AntlrTokenManager(new SwiftLexer(charStream), sourceCode.getFileName()); } } From 94f9ba36c8ad624ea1d2932bfee67e021bbe20ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Mart=C3=ADn=20Sotuyo=20Dodero?= Date: Mon, 15 Oct 2018 01:43:27 -0300 Subject: [PATCH 6/6] Update changelog, refs #1338 --- docs/pages/release_notes.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b99f8d5969..02d57d8465 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -14,6 +14,13 @@ This is a {{ site.pmd.release_type }} release. ### New and noteworthy +#### Improved Golang CPD Support + +Thanks to the work of [ITBA](https://www.itba.edu.ar/) students [Matías Fraga](https://github.com/matifraga), +[Tomi De Lucca](https://github.com/tomidelucca) and [Lucas Soncini](https://github.com/lsoncini), +Golang is now backed by a proper Antlr Grammar. This means CPD is now better at detecting duplicates, +as comments are recognized as such and ignored. + ### Fixed Issues * java @@ -28,6 +35,7 @@ This is a {{ site.pmd.release_type }} release. ### External Contributions +* [#1338](https://github.com/pmd/pmd/pull/1338): \[core] [cpd] Generalize ANTLR tokens preparing support for ANTLR token filter - [Matías Fraga](https://github.com/matifraga) and [Tomi De Lucca](https://github.com/tomidelucca) * [#1366](https://github.com/pmd/pmd/pull/1366): \[java] Static Modifier on Internal Interface pmd #1356 - [avishvat](https://github.com/vishva007) * [#1368](https://github.com/pmd/pmd/pull/1368): \[doc] Updated outdated note in the building documentation. - [Maikel Steneker](https://github.com/maikelsteneker) * [#1374](https://github.com/pmd/pmd/pull/1374): \[java] Simplify check for 'Test' annotation in JUnitTestsShouldIncludeAssertRule. - [Will Winder](https://github.com/winder)